扩展Acegi框架 自定义权限处理

Acegi默认不支持RBAC权限模型,需要自己扩展。对于数据的获取默认是SQL,也需要扩展。

public class RdbmsEntryHolder implements Serializable{
	
	private static final long serialVersionUID = 2317309106087370323L;
	
	//保护的URL模式
	private String url;
	
	//要求的角色集合
	private ConfigAttributeDefinition cad;
	
	public String getUrl() {
		return url;
	}
	
	public ConfigAttributeDefinition getCad() {
		return cad;
	}
	
	public void setUrl(String url) {
		this.url = url;
	}
	
	public void setCad(ConfigAttributeDefinition cad) {
		this.cad = cad;
	}	
}

public class RdbmsFilterInvocationDefinitionSource extends JdbcDaoSupport implements FilterInvocationDefinitionSource {

	protected static final Log logger = LogFactory.getLog(RdbmsFilterInvocationDefinitionSource.class);
	
	private SecuredUrlDefinition rdbmsInvocationDefinition;

	private PathMatcher pathMatcher = new AntPathMatcher();
	
	private Ehcache webresdbCache;
	
	private IBaseDAO baseDAO;

	public ConfigAttributeDefinition getAttributes(Object object)
			throws IllegalArgumentException {
		logger.info("starting method getAttributes");
		if ((object == null) || !this.supports(object.getClass())) {
			throw new IllegalArgumentException("抱歉,目标对象不是FilterInvocation类型");
		}
		// 抽取出待请求的URL
		String url = ((FilterInvocation) object).getRequestUrl();
		logger.info("请求的url: "+url);
		
		List list = this.getRdbmsEntryHolderList();
		if (list == null || list.size() == 0)
			return null;
		int firstQuestionMarkIndex = url.indexOf("?");
		if (firstQuestionMarkIndex != -1) {
			url = url.substring(0, firstQuestionMarkIndex);
		}
		Iterator iter = list.iterator();
		while (iter.hasNext()) {
			RdbmsEntryHolder entryHolder = (RdbmsEntryHolder) iter.next();			
			boolean matched = pathMatcher.match(entryHolder.getUrl(), url);
			if (logger.isDebugEnabled()) {
				logger.debug("匹配到如下URL: '" + url + ";模式为 "
						+ entryHolder.getUrl() + ";是否被匹配:" + matched);
			}
			if (matched) {
				return entryHolder.getCad();
			}
		}
		logger.info("ending method getConfigAttributeDefinitions");
		return null;
	}

	public Iterator getConfigAttributeDefinitions() {
		logger.info("starting method getConfigAttributeDefinitions");
        Set set = new HashSet();
        Iterator iter = this.getRdbmsEntryHolderList().iterator();
        while (iter.hasNext()) {
        	RdbmsEntryHolder entryHolder = (RdbmsEntryHolder) iter.next();
            set.add(entryHolder.getCad());
        }
        return set.iterator();
	}

	public boolean supports(Class clazz) {
		logger.info("starting method supports");
		if (FilterInvocation.class.isAssignableFrom(clazz)) {
			return true;
		} else {
			return false;
		}
	}

	protected void initDao() throws Exception {
		logger.info("starting method initDao");
		this.rdbmsInvocationDefinition = new SecuredUrlDefinition(baseDAO);
		if(this.webresdbCache == null)
			throw new IllegalArgumentException("必须为RdbmsFilterInvocationDefinitionSource配置一EhCache缓存");
	}

	private List getRdbmsEntryHolderList(){
		logger.info("starting method getRdbmsEntryHolderList");
		List list = null;
		Element element = this.webresdbCache.get("webres");
		if(element != null){
			list = (List)element.getValue();
		} else {
			list = this.rdbmsInvocationDefinition.execute();			
			Element elem = new Element("webres", list);
			this.webresdbCache.put(elem);
		}
		logger.info("ending method getRdbmsEntryHolderList.list size :"+list.size());
		return list;
	}
	
	public void setWebresdbCache(Ehcache webresdbCache) {
		this.webresdbCache = webresdbCache;
	}
	
	public void setBaseDAO(IBaseDAO baseDAO) {
		this.baseDAO = baseDAO;
	}	
}

/**
 * Hibernate实现获取角色,Jdbc实现获取资源.
 * @author xiongyuan
 */
public class RdbmsSecuredUrlDefinition extends MappingSqlQuery{

	protected static final Log logger = LogFactory.getLog(RdbmsSecuredUrlDefinition.class);	
	
	private IBaseDAO baseDAO;

	protected RdbmsSecuredUrlDefinition(DataSource ds,IBaseDAO baseDAO) {
        super(ds, "SELECT * FROM auth");      
    	logger.info("进入到RdbmsInvocationDefinition构建器中.........");
    	this.baseDAO = baseDAO;
        compile();
    }

    protected Object mapRow(ResultSet rs, int rownum)
        throws SQLException {    
    	StringBuffer msg = new StringBuffer();
    	RdbmsEntryHolder rsh = new RdbmsEntryHolder();
    	//设置URL
    	int urlid = rs.getInt("authid");
    	String url = rs.getString("authName");
    	msg.append(url+" 对应的ROLE列表...");    	
    	rsh.setUrl(url);
        ConfigAttributeDefinition cad = new ConfigAttributeDefinition();  
        
        /*使用逗号分割role的方案
         * String[] tokens = 
        		StringUtils.commaDelimitedListToStringArray(rs.getString("rolename").trim());
        for(int i = 0; i < tokens.length;++i)
        	cad.addConfigAttribute(new SecurityConfig(tokens[i]));
        */  
        
        //使用自定义表结构后的方案
        String hql = "FROM RoleAuth ra where ra.auth.authid=?";
        List list = baseDAO.find(hql, urlid);
		Iterator iterator = list.iterator();
		while (iterator.hasNext()) {
			RoleAuth obj = (RoleAuth)iterator.next();			
			msg.append(obj.getRole().getRoleName()+",");
			cad.addConfigAttribute(new SecurityConfig(obj.getRole().getRoleName()));
		}
		logger.info(msg);
        //设置角色集合
       rsh.setCad(cad);    	
       return rsh;
    }
}

/**
 * Hibernate实现获取角色权限和资源列表
 * @author xiongyuan
 */
public class SecuredUrlDefinition {

	private static final Log logger = LogFactory.getLog(SecuredUrlDefinition.class);

	private IBaseDAO baseDAO;

	private String loadSecuredUrl = "FROM Auth";

	private String loadRoleForUrl = "FROM RoleAuth ra where ra.auth.authid=?";

	public SecuredUrlDefinition(IBaseDAO baseDAO) {
		logger.info("进入到SecuredUrlDefinition构建器中.........");
		this.baseDAO = baseDAO;
	}

	private RdbmsEntryHolder mapRow(Auth auth) throws SQLException {
		StringBuffer msg = new StringBuffer();		
		// 设置URL
		int urlid = auth.getAuthid();
		String url = auth.getAuthName();
		msg.append(url + " 对应的ROLE列表...");
		RdbmsEntryHolder rsh = new RdbmsEntryHolder();
		rsh.setUrl(url);
		ConfigAttributeDefinition cad = new ConfigAttributeDefinition();
		// 使用自定义表结构后的方案
		List list = baseDAO.find(loadRoleForUrl, urlid);
		Iterator iterator = list.iterator();
		while (iterator.hasNext()) {
			RoleAuth obj = (RoleAuth) iterator.next();
			msg.append(obj.getRole().getRoleName() + ",");
			cad.addConfigAttribute(new SecurityConfig(obj.getRole().getRoleName()));
		}
		logger.info(msg);
		// 设置角色集合
		rsh.setCad(cad);
		return rsh;
	}

	public List execute() {
		List<RdbmsEntryHolder> entryHolderList = new ArrayList<RdbmsEntryHolder>();
		try {
			List securedUrl = baseDAO.find(loadSecuredUrl);
			for (int i = 0; i < securedUrl.size(); i++) {
				Auth auth = (Auth) securedUrl.get(i);				
				entryHolderList.add(mapRow(auth));
			}
		} catch (SQLException e) {			
			e.printStackTrace();
		}
		return entryHolderList;
	}

	public void setLoadRoleForUrl(String loadRoleForUrl) {
		this.loadRoleForUrl = loadRoleForUrl;
	}

	public void setLoadSecuredUrl(String loadSecuredUrl) {
		this.loadSecuredUrl = loadSecuredUrl;
	}
}




你可能感兴趣的:(数据结构,sql,框架,Hibernate,Acegi)