问题描述:Acegi的标签库配置正确,而<authz:authorize..>中ifAllGranted和ifAnyGranted都不起作用,但是ifNotGranted起作用。
解决方法:查看web.xml,把Acegi的Filter调到最前面。比如有sitemesh的filter,也有acegi的,一定要把acegi的放在前面。
今天晚上被Acegi的Tag Library折腾了2个小时。
事情是这样的,本来想用Acegi的标签库来判断用户角色并显示相应的链接,比如说
xml 代码
- <authz:authorize ifAllGranted="ANONYMOUS">
- <span><a href="<%=request.getContextPath()%>/jsp/user/register.jsp">注册</a> </span>
- <span><a href="<%=request.getContextPath()%>/jsp/index.jsp">登录</a> </span>
- </authz:authorize>
- <authz:authorize ifAnyGranted="ADMIN,USER">
- <span class="last"><a href="<%=request.getContextPath()%>/logout.htm">注销</a> </span>
- </authz:authorize>
authz的用法就不介绍了,文档讲的比较明白,意思也很明了。上面的代码就是说当当前用户是ANONYMOUS权限的时候,就显示登录和注册链接,当当前用户是管理员或者普通用户的时候,就显示注销链接。
于是在taglib.jsp里面加入了
xml 代码
- <%@ taglib prefix="authz" uri="http://acegisecurity.org/authz" %>
就应该可以用啦。但是很奇怪,上面两个好像都不起作用。用ifNotGranted却好用。这就怪了,难道还分方法的?于是把AcegiSecurity的源码找出来,开始追根溯源。
<authz:authorize..>对应的是AuthorizeTag.java,当然,主要是doStartTag方法。基本的逻辑是这样,先获得当前用户的Authentication,然后获得页面中属性的内容,然后比较,如果符合,则显示标签里面的内容,否则跳过标签的内容。
调试看了看,发现页面上的内容都获得到了,但是最后却return Tag.SKIP_BODY;了,那就应该是获得当前用户的Authentication的时候出错了。经过艰难的调试,发现匿名的时候,
java 代码
- Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
中,currentUser居然是null。而我同时在另一个类里面却能获得ANONYMOUS。又打印SecurityContextHolder.getContext(),也是Null Authentication,无语了,完全一样的用法啊?查了查Acegi的文档,说SecurityContextHolder使用一个ThreadLocal来保存,难道页面的标签库和Spring中的一些类属于不同thread?但是我打印Thread.currentThread又是一样的。。。
后来在spring的论坛上搜索到类似问题,“Authz tags do not work in JSPs under certain condition”(http://forum.springframework.org/showthread.php?t=32189),才找到问题的所在,问题解决人说:
Filter order is important, we know that, it's drummed in by Acegi docs and forum posts left right and centre. But (for me at least) you just focus on the FilterChainProxy. However, before Acegi gets hold of any requests the web.xml must hand them over. Filter order is declared there too and is explicit in the order of your <filter> declarations, so if like me you also have a filter for your action/controller framework, then this must be declared after (below) the Acegi one.
果然,把我在web.xml中的sitemesh的filter放到acegi的filter后面之后,问题就解决了。
至于为什么会导致SecurityContextHolder.getContext()的不同,我想应该是sitemesh先Filter,先走到页面那一块,Authz已经执行了,但这个时候同样的页面还没被Acegi的Filter拦截,所以就出现了上面的问题(个人理解,待验证)。
分享到:
相关推荐
实战Acegi:使用Acegi作为基于Spring框架的WEB应
实战Acegi:使用Acegi作为基于Spring框架的WEB应用的安全框架.rar
实战Acegi:使用Acegi作为基于Spring框架的WEB应用的安全框架.pdf
Acegi是一个专门为SpringFramework应用提供安全机制的开放源代码项目,全称为Acegi Security System for Spring,当前版本为 0.8.3。它使用了Spring的方式提供了安全和认证安全服务,包括使用Bean Context,拦截器和...
acegi,acegi,acegi
JAVA开发专家:敏捷Acegi、CAS:构建安全的Java系统 pdf
不错的ACEGI 教程
Acegi文档 spring acegi 详细文档
实战Acegi:使用Acegi作为基于Spring框架的WEB应用的安全框架
acegi 框架 介绍 spring 安全
关于Acegi的安全框架,里面有Acegi的实例,讲述得挺清楚的,
Acegi安全系统,是一个用于Spring Framework的安全框架,能够和目前流行的Web... 在Acegi安全系统中,需要被认证的用户,系统或代理称为"Principal"。Acegi安全系统和其他的安全系统不同,它并没有角色和用户组的概念。
Acegi能做什么 Acegi的体系结构 Acegi核心组件 典型的web认证过程 Acegi的登陆认证 Acegi对安全对象的访问控制 Filter 组件 Acegi的不足之处
acegi-security 1.0.2.jar
包含acegi-security-1.0.7.jar,acegi-security-1.0.7-sources.jar,acegi-security-cas-1.0.7.jar,acegi-security-cas-1.0.7-sources.jar,acegi-security-catalina-1.0.7.jar,acegi-security-catalina-1.0.7-...
1、一个Acegi的例子,可以运行 2、一个很好的学Acegi的网址,0基础学习Acegi,强烈推荐 3、有什么问题可以发邮件heroshen@126.com讨论
acegi,spring的安全验证框架
Acegi安全系统,是一个用于Spring Framework的安全框架,能够和目前流行的Web容器无缝集成。它使用了Spring的方式提供了安全和认证安全服务,包括使用Bean Context,拦截器和面向接口的编程方式。因此,Acegi安全...
acegi与cas集成 <!-- ========= Acegi as a CAS Client的配置============= --> class="org.acegisecurity.ui.cas.CasProcessingFilter"> ref="authenticationManager" /> value="/login.do?...