此节将要了解的是AnonymousProcessingFilter、RememberMeProcessingFilter和LogoutFilter三个过滤器

1、AnonymousProcessingFilter

在大部分企业应用中,存在许多不需要用户登录就可以访问的资源,比如登录页面、退出页面、主页等。鉴于此,Acegi提供了匿名认证服务。这样能够使所有的Web资源得到保护,而不是某些资源不设权限控制,让任何人访问,这样Acegi使Web安全策略模型应用的非常完美。与此同时,SecurityContextHolder(SecurityContext)将始终持有Authentication对象,因此代码的健壮性、可读性也会得到增强。

  AnonymousProcessingFilter,该过滤器是用来处理匿名用户的。如果用户尚未登录,将生成一个匿名用户的Authentication存放到ContextHolder中。即当不存在任何授权信息时,自动为Authentication对象添加userAttribute中定义的匿名用户权限。

<bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
<property name="key" value="changeThis" />
<property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />
</bean>

  说明:

    key:用于指定用户的名称,其实这个属性指定的值只是一个简单的标识符,可以自己取值。

    userAttribute:用于指定匿名用户的密码(anonymousUser)、权限信息(ROLE_ANONYMOUS)和启用状态(enabled/disabled),这里anonymousUser实际上是用户名。

  另外,和AuthenticationProcessingFilter的一样,AnonymousProcessingFilter也有自己的AuthenticationProvider,即AnonymousProcessingFilter。

<bean class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="changeThis" />
</bean>

  此处的key一般与AnonymousProcessingFilter中的key保持一致,用于保证Authentication对象的真实性,当然这只是Acegi内部的一个设计细节,开发者直接提供自身的key属性取值即可。同样将该Provider加到authenticationManager的providers属性列表中。(如果不提供AnonymousAuthenticationProvider,同样能实现匿名认证的功能,或者key不相同也没影响,这一点暂时不太明白,如果有谁清楚的请留言给我,让我增加见识。)

2、RememberMeProcessingFilter
  该Filter会在用户登录后,在本地机器上记录用户cookies信息,这样下次访问就不用再登录了。它还负责对所有HTTP请求进行拦截,当发现SecurityContextHolder中没有包含有效的Authentication对象时,自动调用RememberMeServices#autoLogin()方法从Cookie中获取用户名/密码的编码串进行自动登录,所以rememberMeProcessingFilter首先要注入一个RememberMeServices Bean。

  rememberMeProcessingFilter通过rememberMeServices获取对应Cookie中用户的UserDetails后,就必须进行用户身份认证。这项工作依然委托给authenticationManager完成,所以我们给rememberMeProcessingFilter注入了authenticationManager Bean。

   authenticationManager如何对基于Cookie的用户凭证进行认证呢?显然,不能采用原来的daoAuthenticationProvider所用的方法,因为Cookie所提供的用户凭证和登录表单提供的用户凭证在格式上存在很大的差异。基于Remember-Me的用户名/密码信息是经过特殊编码的字符串,Acegi通过RememberMeAuthenticationProvider负责对基于Cookie的用户凭证信息进行认证。所以你必须将该认证提供者添加到authenticationManager中。

<bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
<property name="authenticationManager" ref="authenticationManager" />
<property name="rememberMeServices" ref="rememberMeServices" /><!-- 增加 -->
</bean>
<bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
<property name="providers">
<list>
<ref local="daoAuthenticationProvider" />
<!-- 增加 -->
<bean class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
<property name="key" value="changeThis" />
</bean>
<!-- 增加 -->
<bean class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
<property name="key" value="foobar" /><!-- key必须和rememberMeServices中的key一致 -->
</bean>
</list>
</property>
</bean>
<!-- 增加, 默认tokenValiditySeconds = 1209600L, 即保留两周 -->
<bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
<property name="userDetailsService" ref="inMemDaoImpl" />
<!-- cookie中的键值, 防止保存到客户端的cookie中的加密串被恶意篡改 -->
<property name="key" value="foobar" />
<!-- cookie有效时间, 单位为秒, 这里设定为5天内不用再登陆 -->
<property name="tokenValiditySeconds" value="432000" />
</bean>
<!--另外,必须在AuthenticationProcessingFilter中加入rememberMeServices。这样,当用户勾选了记住密码并登录后,rememberMeServices会将用户信息保存到Cookie中-->
<bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter">
……
<property name="rememberMeServices" ref="rememberMeServices" /><!-- 增加, 可别忘了此处 -->
</bean>

3、LogoutFilter

该Filter负责处理退出登录后所需要的清理工作。包括:
    1) 销毁session
    2) 清空 ContextHolder
    3) 把rememberMeServices从cookies中清除掉
    4) 最后重定向到指定的退出登陆页面。

<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
<constructor-arg value="/index.jsp"/> <!-- URL redirected to after logout 退出页面url -->
<constructor-arg>
<list>
<ref bean="rememberMeServices"/><!-- 用于清空cookies -->
<bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
</list>
</constructor-arg>
</bean>

  最后,请注意,Acegi默认的自动登陆设定参数名为_acegi_security_remember_me,注销链接为/j_acegi_logout。
        登录时,在页面添加以下代码:

<input type="checkbox" name="_acegi_security_remember_me">  

  退出时,在页面添加以下代码:

<a href="<%=request.getContextPath() %>/j_acegi_logout">Logout</a>  

学习Acegi应用到实际项目中(3)的更多相关文章

  1. 学习Acegi应用到实际项目中(10)- 保护业务方法

    前面已经讲过关于保护Web资源的方式,其中包括直接在XML文件中配置和自定义实现FilterInvocationDefinitionSource接口两种方式.在实际企业应用中,保护Web资源非常重要, ...

  2. 学习Acegi应用到实际项目中(2)

    Acegi应用到实际项目中(1)是基于BasicProcessingFilter的基本认证,这篇改用AuthenticationProcessingFilter基于表单的认证方式. 1.authent ...

  3. 学习Acegi应用到实际项目中(7)- 缓存用户信息

    在默认情况下,即在用户未提供自身配置文件ehcache.xml或ehcache-failsafe.xml时,EhCache会依据其自身Jar存档包含的ehcache-failsafe.xml文件所定制 ...

  4. 学习Acegi应用到实际项目中(1)

    在此,本人声明,我处于菜鸟阶段,文章的内容大部分摘自zhanjia的博客(http://zhanjia.iteye.com/category/43399),旨在学习,有很多地方,我理解不够透彻,可能存 ...

  5. 学习Acegi应用到实际项目中(12)- Run-As认证服务

    有这样一些场合,系统用户必须以其他角色身份去操作某些资源.例如,用户A要访问资源B,而用户A拥有的角色为AUTH_USER,资源B访问的角色必须为AUTH_RUN_AS_DATE,那么此时就必须使用户 ...

  6. 学习Acegi应用到实际项目中(11)- 切换用户

    在某些应用场合中,可能需要用到切换用户的功能,从而以另一用户的身份进行相关操作.这一点类似于在Linux系统中,用su命令切换到另一用户进行相关操作. 既然实际应用中有这种场合,那么我们就有必要对其进 ...

  7. 学习Acegi应用到实际项目中(9)- 实现FilterInvocationDefinition

    在实际应用中,开发者有时需要将Web资源授权信息(角色与授权资源之间的定义)存放在RDBMS中,以便更好的管理.事实上,一般的企业应用都应当如此,因为这样可以使角色和Web资源的管理更灵活,更自由.那 ...

  8. 学习Acegi应用到实际项目中(8)- 扩展UserDetailsService接口

    一个能为DaoAuthenticationProvider提供存取认证库的的类,它必须要实现UserDetailsService接口: public UserDetails loadUserByUse ...

  9. 学习Acegi应用到实际项目中(5)

    实际企业应用中,用户密码一般都会进行加密处理,这样才能使企业应用更加安全.既然密码的加密如此之重要,那么Acegi(Spring Security)作为成熟的安全框架,当然也我们提供了相应的处理方式. ...

  10. 学习Acegi应用到实际项目中(4)

    此节介绍:ConcurrentSessionFilter. 在Acegi 1.x版本中,控制并发HttpSession和Remember-Me认证服务不能够同时启用,它们之间存在冲突问题. 在一些应用 ...

随机推荐

  1. [UE4]Window Title Bar Area

    一.Window Title Bar Area.windows窗口拖拽控件 二.window Buttons Enabled,在控件的右上角显示:最小化.最大化,关闭按钮; Toggle Fullsc ...

  2. 涨姿势:Java 分业务、分级别实现自定义日志打印

    自定义日志级别 通常的日志框架都有以下几个级别,从低到高TRACE,DEBUG,INFO,WARN,ERROR,FATAL. 默认情况,假如我们定义日志打印级别INFO,它会把大于等于INFO级别的日 ...

  3. 1、ZooKeeper 基本概念、使用方法、实践场景

    ZooKeeper 基本概念 ZooKeeper 是面向分布式应用的协调服务,其实现了树形结构的数据模型(与文件系统类似),并且提供了简洁的编程原语.ZooKeeper 能够作为基础,用于构建更高层级 ...

  4. 内训--2小时 Word精髓

    企业内部使用Word最常见就是用来写产品手册与合同,产品手册是书版(即可以出版,与买到的书类似),合同重点是修订.Word的精髓在于样式,或者说在企业办公使用,学会样式就可以了.什么域.宏.VBA几乎 ...

  5. 涂抹mysql笔记-mysql数据库文件结构

    <>初始化选项文件:默认位置:windows平台 windir\my.ini windir可通过echo $WINDIR$查看 系统盘的根目录即:c:\my.ini installdir\ ...

  6. MySQL——navicat 连接 mysql 出现1251Client does not support authentication protocol requested by server的解决方案

    前期修改root密码问题(首次安装的root密码是空,直接Enter就行): cmd用管理员身份进入,然后输入 mysqladmin -u root -p password newpassword 需 ...

  7. nodejs+mocha+supertest+chai进行测试(only demo)

    1.nodejs安装成功 (上一篇:brew install nodejs) 2.mocha安装成功 npm install -g mocha 解释: -g代表global,全局的意思.此处mocha ...

  8. svg转png

    svg转png网络上常用的方式有两种: 1.直接转base64放到图片src进行显示,测试效果不佳,始终报方法问题. 2.先转canvas,再转为png图,测试效果可以但svg透明背景到了canvas ...

  9. block引用外部变量原理

    block在赋值时才会生成对应的block结构体实例(结构体数据结构在编译时已经生成),赋值时会扫一遍里面引用的外部变量(嵌套block中的外部变量也算,只不过嵌套block中的外部变量会被内外两个b ...

  10. proposal-cancelable-promises

    fetch 从来就没行过,最大的优势就是"新标准",但是 proposal-cancelable-promises 被 withdrawn,就导致了 fetch 发起的请求不可能被 ...