Acegi(八): securityContextHolderAwareRequestFilter

本文详细解析了Acegi Security框架中SecurityContextHolderAwareRequestFilter的配置与作用,包括如何配置及其实现原理,解释了该过滤器如何确保Acegi的安全认证信息能够正确地覆盖Web容器自身的认证信息。

  上篇 中我们说了下 LogoutFilter的配置, 这篇里接着看另一个常见的配置SecurityContextHolderAwareRequestFilter. 下面先看怎么把它配置到Acegi里.

    应该说对 securityContextHolderAwareRequestFilter 的配置要比LogoutFilter的更简单些. 有以下两步:
         Step1: 定义一个名为securityContextHolderAwareRequestFilter的bean, 如下所示:

             

<bean id="securityContextHolderAwareRequestFilter"     
             class="org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter" />
 

             呵呵, 简单地我就有些不好意思往这写了. 就这么一个干巴巴的类, 别什么属性要配置的.


         Step2: 把定义好的 securityContextHolderAwareRequestFilter放到 filterInvocationDefinitionSource里, 如下所示:
               /**=httpSessionContextIntegrationFilter,logoutFilter,authenticationProcessingFilter,securityContextHolderAwareRequestFilter ,exceptionTranslationFilter,filterInvocationInterceptor
            

    上面是对它的配置, 这个配置有些干巴巴的, 那它究竟有什么用呢? 我们接着往下看, 那将是一个丰富多彩的世界.

    SecurityContextHolderAwareRequestFilter类名怎么这么长? 也看不出什么有用的信息啊. 不过, 看文档得知 SecurityContextHolderAwareRequestFilter的作用是:将传来的 request用一个 HttpServletRequestWrapper封装下再传给 filterChain. 我们不禁要问? 为什么要这么做呢? 也就是说这么做有什么好处呢?

    要弄通这个问题, 我们得看这个Filter对传的 request做了些什么手脚, 也就是说是以什么样的一个 HttpServletRequestWrapper来封装了传来的 request. 在Acegi中我们发现就有两个 HttpServletRequestWrapper的子类: SecurityContextHolderAwareRequestWrapper和 SavedRequestAwareWrapper. 它们又有什么样的特质呢? 发现 SavedRequestAwareWrapper是 SecurityContextHolderAwareRequestWrapper的子类, 为了钻研的方便, 我们先看父类 SecurityContextHolderAwareRequestWrapper , 所谓有其父必有其子嘛.

    先解剖下这个类, 这个类只有一个属性authenticationTrustResolver(其实它没什么多大的用处, 待会再细说), 覆盖了 HttpServletRequestWrapper的三个方法: getRemoteUser, getUserPrincipal, isUserInRole.
    (这里先顺便说下, 我以前一直没注意到上面的这三个方法是接口里定义的, 看来Servlet规范里早就考虑到Security方面的问题了; 另一个没注意到的是, 原来 Principal是Java标准类security包下的定义的接口, 而Acegi里重要的接口 Authentication是继承自 Principal )
    于是问题就转为为什么要单独再覆盖这三个方法了.那得看这三个方法又都干了什么. 看方法的实现, 发现它们实际上是做了同样的事, 即通过 SecurityContextHolder.getContext().getAuthentication()拿到 Authentication后再get出String类型的 RemoteUser,或 Principal类型信息, 或看这个 Authentication是否有指定的权限. 也就是说它们把Acegi里自身的验证信息放到Servlet规范里体现的对Security的支持!

    那为什么非要用Acegi的认证信息来替换或填充Servlet规范中 Security信息呢? 我想有这么几点好处:
         1, 替换掉Web容器自身的认证信息. 拿Tomca为例, 我们知道在Tomcat中可以配置管理权限的, 若Tomcat自身配置了权限管理, 而Acegi不做什么处理的话, 程序员从 HttpServletRequest里通过调用上面三种方法得到的Security方面的信息就不是通过Acegi配置的了, 那样岂不就乱套了? Acegi自身的Security作用也就给架空了, 这还得了? 于是Acegi就有果断地通过 SecurityContextHolderAwareRequestWrapper把漏洞给补上了.
         2, 还有一个可能的好处, 那就是通过这种覆盖处理, 程序员可以在Action或JSP中方便地得到当前登录用户的信息, 而不必在系统中揉合进Acegi自己的API. 项目中这样的反例太多了.

    通过上面的分析,再看类的名字 SecurityContextHolderAwareRequestFilter, 这样也就好理解了, 真是顾名思义! 这个名字表达的意思是说, 这个Filter是让Request 来aware下SecurityContextHolder里的信息, 这个让它Aware正是通过覆盖三个方法实现的.

    好了, 这篇就写到这里, 下一篇中我们将看 SecurityContextHolderAwareRequestFilter子类 SavedRequestAwareWrapper又加了些什么功能. Until the next.

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值