`
iMzw
  • 浏览: 190842 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

acegi动态资源配置的另一种实现

    博客分类:
  • Java
阅读更多
相关文章
http://www.iteye.com/article/17538
http://www.iteye.com/topic/18635

下面为org.acegisecurity.intercept.web。FilterSecurityInterceptor 的源码摘录

/**
 * Performs security handling of HTTP resources via a filter implementation.<p>The
 * <code>ObjectDefinitionSource</code> required by this security interceptor is of type {@link
 * FilterInvocationDefinitionSource}.</p>
 *  <P>Refer to {@link AbstractSecurityInterceptor} for details on the workflow.</p>
 *
 * @author Ben Alex
 * @version $Id: FilterSecurityInterceptor.java 1496 2006-05-23 13:38:33Z benalex $
 */
public class FilterSecurityInterceptor extends AbstractSecurityInterceptor implements Filter {
    //~ Static fields/initializers =====================================================================================

    private static final String FILTER_APPLIED = "__acegi_filterSecurityInterceptor_filterApplied";

    //~ Instance fields ================================================================================================

   private FilterInvocationDefinitionSource objectDefinitionSource;
   。。。省略部分内容
    public void setObjectDefinitionSource(FilterInvocationDefinitionSource newSource) {
        this.objectDefinitionSource = newSource;
    }

    public void setObserveOncePerRequest(boolean observeOncePerRequest) {
        this.observeOncePerRequest = observeOncePerRequest;
    }
}

通常的配置为:
<bean id="filterSecurityInterceptor"
		class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
	<property name="authenticationManager"
		ref="authenticationManager">
	</property>
	<property name="accessDecisionManager"
			ref="httpRequestAccesssDecisionManager">
	</property>
	<property name="objectDefinitionSource">
		<value>
                PATTERN_TYPE_APACHE_ANT
			/admin/securedpage.jsp=ROLE_ADMIN
			/admin/securedpage.jsp=ROLE_UNIT
                </value>
	</property>
</bean>

我们可以看出,其实我们只需要提供一个FilterInvocationDefinitionSource接口的实现,就可以完成从数据库读取资源配置的工作。
以下为我写的一个实现(参考了阿飞的书《敏捷Acegi,Cas》),没有使用缓存,实际的环境中应该缓存数据,避免每次查询数据库。
数据库关系图:见附件

关键类
package net.imzw.acegi;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.acegisecurity.ConfigAttributeDefinition;
import org.acegisecurity.intercept.web.FilterInvocation;
import org.acegisecurity.intercept.web.FilterInvocationDefinitionSource;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;

public class RdbmsFilterInvocationDefinitionSource extends JdbcDaoSupport
		implements FilterInvocationDefinitionSource {

	private RdbmsFilterInvocationDefinition rdbmsFilterInvocationDefinition;

	private PathMatcher pathMatcher = new AntPathMatcher();

	public ConfigAttributeDefinition getAttributes(Object object)
			throws IllegalArgumentException {
		if ((object == null) || !this.supports(object.getClass())) {
			throw new IllegalArgumentException(
					"Object must be a FilterInvocation");
		}

		String url = ((FilterInvocation) object).getRequestUrl();
	
		return this.lookupAttributes(url);
	}

	@Override
	protected void initDao() throws Exception {
		this.rdbmsFilterInvocationDefinition = new RdbmsFilterInvocationDefinition(
				this.getDataSource());
	}

	public ConfigAttributeDefinition lookupAttributes(String url) {
		if(logger.isDebugEnabled()){
			logger.debug("lookup Attributes for "+url);
		}
		List<RdbmsEntryHolder> hodlers = getRdbmsEntryHolderList();
		if (hodlers == null || hodlers.size() == 0) {
			return null;
		}
		int firstQuestionMarkIndex = url.indexOf("?");

		if (firstQuestionMarkIndex != -1) {
			url = url.substring(0, firstQuestionMarkIndex);
		}

		Iterator<RdbmsEntryHolder> ite = hodlers.iterator();
		while (ite.hasNext()) {
			RdbmsEntryHolder holder = ite.next();
			boolean matched = pathMatcher.match(holder.getUrl(), url);
			if (matched) {
				return holder.getConfigAttributeDefinition();
			}
		}
		return null;
	}

	public boolean supports(Class clazz) {
		return FilterInvocation.class.isAssignableFrom(clazz);
	}

	public Iterator getConfigAttributeDefinitions() {
		Set<ConfigAttributeDefinition> cads=new HashSet<ConfigAttributeDefinition>();
		List<RdbmsEntryHolder> hodlers = getRdbmsEntryHolderList();
		Iterator<RdbmsEntryHolder> ite = hodlers.iterator();
		while (ite.hasNext()) {
			 cads.add(ite.next().getConfigAttributeDefinition());
		}
		return cads.iterator();
	}

	public RdbmsFilterInvocationDefinition getRdbmsFilterInvocationDefinition() {
		return rdbmsFilterInvocationDefinition;
	}

	public void setRdbmsFilterInvocationDefinition(
			RdbmsFilterInvocationDefinition rdbmsFilterInvocationDefinition) {
		this.rdbmsFilterInvocationDefinition = rdbmsFilterInvocationDefinition;
	}

	private List<RdbmsEntryHolder> getRdbmsEntryHolderList() {
		List<RdbmsEntryHolder> list = getRdbmsFilterInvocationDefinition()
				.execute();
		if(logger.isDebugEnabled()){
			for(RdbmsEntryHolder h:list){
				logger.debug(h);
			}
		}
		return list;
	}
}


配置如下:
<bean id="filterSecurityInterceptor"
		class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
		<property name="authenticationManager"
			ref="authenticationManager">
		</property>
		<property name="accessDecisionManager"
			ref="httpRequestAccesssDecisionManager">
		</property>
		<property name="objectDefinitionSource">
			<ref local="rdbmsFilterInvocationDefinitionSource" />
		</property>
	</bean>
<bean id="rdbmsFilterInvocationDefinitionSource"
		class="net.imzw.acegi.RdbmsFilterInvocationDefinitionSource">
		<property name="dataSource">
			<ref local="dataSource" />
		</property>
	</bean>

由于项目的工期很紧(国内好像没有那个项目工期不紧的),没有时间将我的思路组织成文章,详细的见附件,不难理解。
注:示例需要jdk1.6,可以自己稍稍改一下就应该可以在jdk1.5下运行。
  • 大小: 20 KB
分享到:
评论
3 楼 iMzw 2007-06-19  
Feiing 写道
呵呵, 楼主莫非没看到我另一篇帖子 ?

http://www.iteye.com/topic/18635

两年前的东西, 也要挖出来,  大可不必


不好意思,我确实没有看到,见笑!
因为最近使用到了Acegi所以就顺道发了出来,如果早看到的话,就不用浪费我半天时间研究Acegi的源码了。谢谢提醒。
关于缓存,我一直用的是Spring-Modules提供的声明式缓存。
另外,不知兄台对Acegi+Spring+dwr的组合有没有接触过?能不能提一些关于权限管理好的建议?

2 楼 iMzw 2007-06-19  
1 楼 Feiing 2007-06-19  
呵呵, 楼主莫非没看到我另一篇帖子 ?

http://www.iteye.com/topic/18635

两年前的东西, 也要挖出来,  大可不必

相关推荐

Global site tag (gtag.js) - Google Analytics