Chinaunix首页 | 论坛 | 博客
  • 博客访问: 714670
  • 博文数量: 147
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-22 10:36
文章分类

全部博文(147)

文章存档

2011年(1)

2010年(1)

2009年(35)

2008年(110)

我的朋友

分类: Java

2008-12-10 18:02:51

Remember-Me认证服务:
1.配置RememberMeProcessFilter过滤器,并且为它提供认证管理器和RememberMeService实例
 

<bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter">
      <property name="authenticationManager"><ref local="authenticationManager"/></property>
      <property name="rememberMeServices"><ref local="rememberMeServices"/></property>
   </bean>
   
   <bean id="rememberMeServices" class="org.acegisecurity.ui.rememberme.TokenBasedRememberMeServices">
      <property name="userDetailsService"><ref local="jdbcDaoImpl"/></property>
      <property name="key"><value>springRocks</value></property>
      <property name="alwaysRemember" value="true"></property>
   </bean>

2.将上述RememberMeProcessingFilter过滤器定义的名字添加到FilterChainProxy定义中

<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
            <value>
                PATTERN_TYPE_APACHE_ANT
                /**=httpSessionContextIntegrationFilter,logoutFilter,basicProcessingFilter,rememberMeProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
            </value>
        </property>
 </bean>

3.定义RememberMeAuthenticationProvider认证提供者

<bean id="authenticationManager"
        class="org.acegisecurity.providers.ProviderManager">
        <property name="providers">
            <list>
                <ref local="daoAuthenticationProvider" />
                <ref local="rememberMeAuthenticationProvider" />
            </list>
        </property>
    </bean>
    
  <bean id="rememberMeAuthenticationProvider" class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider">
      <property name="key"><value>springRocks</value></property>
   </bean>
  其暴露出来的key属性必须和rememberMeServices中的key属性取值相同

4.将上述rememberMeServices定义暴露给BasicProcessingFilter

<bean id="basicProcessingFilter"
        class="org.acegisecurity.ui.basicauth.BasicProcessingFilter">
        <property name="authenticationManager" ref="authenticationManager" />
        <property name="authenticationEntryPoint" ref="basicProcessingFilterEntryPoint" />
         <property name="rememberMeServices" ref="rememberMeServices"></property>
    </bean>
默认时,rememberme会借助Cookie技术一同完成客户端和服务端的认证处理    
启用了RememberMe服务,在第一次登陆成功后,关闭浏览器,再次登陆就不需要输入用户名和密码,默认是14天!    

 

 

退出服务
点击退出时(j_acegi_logout),就会退出当前的web应用,重新登陆时,必须在输入用户名和密码!(不管是否启用remember-me服务)
1.定义相应的LogoutFilter过滤器

<bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter">
      <constructor-arg value="/index.jsp"/>
      <constructor-arg>
         <list>
              <ref local="rememberMeServices" />
              <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/>
         </list>
      </constructor-arg>
   </bean>

2.将logoutFilter过滤器添加到FilterChainProxy拦截器链中

<bean id="filterChainProxy" class="org.acegisecurity.util.FilterChainProxy">
        <property name="filterInvocationDefinitionSource">
            <value>
                PATTERN_TYPE_APACHE_ANT
                /**=httpSessionContextIntegrationFilter,logoutFilter,basicProcessingFilter,rememberMeProcessingFilter,exceptionTranslationFilter,filterInvocationInterceptor
            </value>
        </property>
    </bean>

3.在具体的web应用中,将某些超连接的url置为"j_acegi_logout"

 

匿名认证服务
在大部分企业应用中,都存在不少不需要用户登陆的web资源,比如登陆页面,退出页面,web应用主页等,鉴于此,acegi提供了匿名登陆服务
1.定义相应的AnonymousProcessingFilter

<bean id="anonymousProcessingFilter" class="org.acegisecurity.providers.anonymous.AnonymousProcessingFilter">
      <property name="key"><value>foobar</value></property>
      <property name="userAttribute"><value>anonymousUser,ROLE_ANONYMOUS</value></property>
   </bean>
 userAttribute属性定义了匿名用户的密码(anonymousUser),权限(ROLE_ANONYMOUS),启用状态(enabled\disabled)
 key属性指定了用户的名称

2.定义AnonymousAuthenticationProvider,并添加到认证管理器中

<bean id="anonymousAuthenticationProvider" class="org.acegisecurity.providers.anonymous.AnonymousAuthenticationProvider">
      <property name="key"><value>foobar</value></property>
   </bean>
   
 <bean id="authenticationManager" class="org.acegisecurity.providers.ProviderManager">
      <property name="providers">
         <list>
            <ref local="daoAuthenticationProvider"/>
            <ref local="anonymousAuthenticationProvider"/>
            <ref local="rememberMeAuthenticationProvider" />
         </list>
      </property>
   </bean>

3.定义应用匿名认证的web资源

<bean id="filterInvocationInterceptor" class="org.acegisecurity.intercept.web.FilterSecurityInterceptor">
      <property name="authenticationManager"><ref bean="authenticationManager"/></property>
      <property name="accessDecisionManager"><ref local="httpRequestAccessDecisionManager"/></property>
      <property name="objectDefinitionSource">
         <value>
             CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
             PATTERN_TYPE_APACHE_ANT
             /index.jsp=ROLE_ANONYMOUS,ROLE_USER
             /hello.htm=ROLE_ANONYMOUS,ROLE_USER
             /logoff.jsp=ROLE_ANONYMOUS,ROLE_USER
             /switchuser.jsp=ROLE_SUPERVISOR
             /j_acegi_switch_user=ROLE_SUPERVISOR
             /acegilogin.jsp*=ROLE_ANONYMOUS,ROLE_USER
                /**=ROLE_USER
         </value>
      </property>
   </bean>     
由上面定义可以看出来/index.jsp /hello.html /logoff.jsp /acegilogin.jsp* 等url不需要用户登陆!

 

揭开SecurityContextHolder的真相:
     用户登陆后,登陆用户的信息会以Authentication对象形式存在,并保存到SecurityContext对象中,
而SecutiryContext对象会存储到SecurityContextHolder中.那么直接借助SecurityContextHolder就可以操作到Authentication对象:

Authentication auth=SecurityContextHolder.getContext().getAuthentication()
Authentication对象默认存储在SecurityContext中,而acegi中内置了很多SecurityContext接口的实现,大部分情况下
acegi内部会直接使用SecurityContextImpl实现类!
     由于存在不同的客户类型,而且它们所处的环境都不一样,比如某些是单个用户使用的桌面系统,而另一些使用的
是不同线程间的交互,切换,考虑到这些不同情况,acegi提供了SecurityContextHolderStrategy策略接口.默认时
SecurityContextHolder会将客户的SecurityContext访问请求委派给这个策略接口
其实现类:
ThreadLocalSecurityContextHolderStrategy采用ThreadLocal类型的变量存储SecurityContext对象,默认的!


InheritableThreadLocalSercurityHolderStrategy采用InheritableThreadLocal类型的变量存储SecurityContext对象


GlobalSecurityContextHolderStrategy采用SecurityContext类型的变量(contextHolder)存储SecurityContext对象


为了切换到不同的SecurityContextHolderStrategy实现类,开发者可以借助两种不同的方法:
1.在启动宿主目标应用的JVM时,提供"acegi.security.strategy"JVM系统参数
2.使用acegi前手工调用SecurityContextHolder暴露的setStrategyName()静态方法.
以上都需要提供字符串值:
MODE_THREADLOCAL(ThreadLocalSecurityContextHolderStrategy)
MODE_INHERITABLETHREADLOCAL(InheritableThreadLocalSercurityHolderStrategy)
MODE_GLOBAL(对应GlobalSecurityContextHolderStrategy)
eg:-Dacegi.security.strategy=MODE_INHERITABLETHREADLOCAL

阅读(2557) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~