了解Acegi第一步
????? 最近在研究spring的认证框架acegi,记录一下自己的理解。
????? Acegi是基于Spring的一个开源的安全认证框架,现在的最新版本是1.0.7。Acegi的特点就是有很多的过滤器,具体项目中能用到哪些过滤器,则进行配置即可。
????? Acegi资源包下载: http://mirrors.ibiblio.org/pub/mirrors/maven2/org/acegisecurity/acegi-security/
????? Acegi的官网: http://www.acegisecurity.org/
????? Acegi是以过滤器的方式来使用的,在WEB程序中,就得在web.xml中配置过滤器,如果在web.xml配置许多的过滤器,肯定会出现配置文件过大和初始化及Filter的管理得问题,Acegi提供了用spring容器来管理Filter的配置方式:
Web.xml文件中:
<filter><filter-name>Acegi-Filter</filter-name><filter-class>org.acegisecurity.util.FilterToBeanProxy</filter-class><init-param><param-name>targetClass</param-name><param-value>org.acegisecurity.util.FilterChainProxy</param-value></init-param></filter>
?applicationContext-acegi-security.xml文件中:
<bean id="filterChainProxy"name="code">Iterator iter = requestMap.iterator(); while (iter.hasNext()) { EntryHolder entryHolder = (EntryHolder) iter.next();//判断请求的url与配置的path是否相符 boolean matched = pathMatcher.match(entryHolder.getAntPath(), url); if (logger.isDebugEnabled()) { logger.debug("Candidate is: '" + url + "'; pattern is " + entryHolder.getAntPath() + "; matched=" + matched); } if (matched) {//如果找到,这返回EntryHolder中的ConfigAttributeDefinition对象,其中保存有对应的Filter列表 return entryHolder.getConfigAttributeDefinition(); } }
?得到了ConfigAttributeDefinition对象,然后得到其中的所有的Filter:
PathBaseFilterInvocationDefinitionMap:obtainAllDefinedFilter(ConfigAttributeDefinition configAttributeDefinition)
Iterator attributes = configAttributeDefinition.getConfigAttributes(); while (attributes.hasNext()) { ConfigAttribute attr = (ConfigAttribute) attributes.next(); String filterName = attr.getAttribute(); if (filterName == null) { throw new IllegalArgumentException("Configuration attribute: '" + attr + "' returned null to the getAttribute() method, which is invalid when used with FilterChainProxy"); } if (!filterName.equals(TOKEN_NONE)) { list.add(this.applicationContext.getBean(filterName, Filter.class)); } } return (Filter[]) list.toArray(new Filter[list.size()]);
????? 其中我们看到如果filterName.equals(TOKEN_NONE),则这个Filter不加入到处理的Filter对列中,所以如果要想某个请求不经过这些过滤器,则可以配成:path=#NONE#
然后FilterChainProxy将所有的过滤器保存在一个VirtualFilterChain对象中,将所有过滤器的调用交给VirtualFilterChain对象:VirtualFilterChain:
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException { if (currentPosition == additionalFilters.length) { if (logger.isDebugEnabled()) { logger.debug(fi.getRequestUrl() + " reached end of additional filter chain; proceeding with original chain"); } fi.getChain().doFilter(request, response); } else { currentPosition++; if (logger.isDebugEnabled()) { logger.debug(fi.getRequestUrl() + " at position " + currentPosition + " of " + additionalFilters.length + " in additional filter chain; firing Filter: '" + additionalFilters[currentPosition - 1] + "'"); } additionalFilters[currentPosition - 1].doFilter(request, response, this); } }
?这样VirtualFilterChain将按filterChainProxy中配置的Filter顺序来一个个执行。
1 楼 d4rkl0rd 2008-12-29 acegi 现在已经是spring security了吧? 2 楼 jiyanliang 2008-12-29 之前使用acegi来做网站的权限管理:经常出现session和acegi中的Context不一致的情况,动不动就出现该访问的访问不了的情况。。。
更重要的是,我在测试的时候还不得不把@Secured去掉。
使用struts2的Interceptor,感觉非常好,所有问题都解决了。