spring security3.x学习(25)_bean配置跑spring security(mysql数据库)

来源:互联网 发布:淘宝新店引流软件 编辑:程序博客网 时间:2024/05/17 00:05
看spring security有一段时间了,一直迷惑于spring security使用的不方便,今天看书的时候,终于提到了自定义的spring security,下边就是书中提出的神图(我是看了一下,没怎么看懂,但是我觉得自己做完再回来看肯定就差不多了。)

直接看配置文件:
[html] view plaincopy
  1. <!-- 配置一个定义的过滤器链 -->  
  2.      <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">  
  3.           <security:filter-chain-map path-type="ant">  
  4.                <security:filter-chain pattern="/**"  
  5.                     filters="  
  6.                      securityContextPersistenceFilter,  
  7.                      usernamePasswordAuthenticationFilter,  
  8.                      anonymousAuthenticationFilter,  
  9.                      filterSecurityInterceptor" />  
  10.           </security:filter-chain-map>  
  11.      </bean>  


这样就可以获得一个自己的过滤器链顺序了。
如果将这与<http>风格的配置进行对比的话,我们要注意以下的配置元素:
1.  默认过滤器链的建立是在处理<http>元素的时候自动包含的并不需要直接配置。尽管使用security命名空间的<custom-filter>重写或扩展标准过滤器链的时候,允许很大程度的灵活性,但它并不能够得到FilterChainProxy本身。
2.  基于URL模式修改过滤器链并不适用于<http>风格的声明。如果应用的某些部分不需要特定的处理这将会有用处,并且能使得过滤器的调用尽可能得少。 需要意识到很重要的一点是,不同于Spring 的一些配置(比较明显的如,在web.xml中的contextConfigLocation),在过滤器的名字之间需要需要使用逗号分隔。

接下来就应该是慢慢配置了:
[html] view plaincopy
  1. <bean id="securityContextPersistenceFilter"   
  2.       class="org.springframework.security.web.context.SecurityContextPersistenceFilter"/>  

"
  SecurityContextPersistenceFilter用来建立SecurityContext,而它被用来贯穿整个request过程以跟踪请求者的认证信息。你可能记得我们在上一章的Spring  MVC代码中,为了得到当前认证过的Principa时,访问过SecurityContext对象。 
"

[html] view plaincopy
  1. <bean id="UsernamePasswordAuthenticationFilter"  
  2.           class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">  
  3.           <property name="authenticationManager" ref="customAuthenticationManager" />  
  4.      </bean>  

"
  正如我们在第二章中详细介绍的那样,UsernamePasswordAuthenticationFilter用来处理form 提交并检查认证存储是否为合法凭证。明确配置这个过滤器,对比security命名空间的配置.
"
[html] view plaincopy
  1. <bean id="anonymousAuthenticationFilter"  
  2.      class="org.springframework.security.web.authentication.AnonymousAuthenticationFilter">  
  3.      <property name="userAttribute" value="anonymousUser,ROLE_ANONYMOUS" />  
  4.      <property name="key" value="BF93JFJ091N00Q7HF" />  
  5. </bean>  

"
我们的站点允许匿名访问。尽管对于比较特殊的条件AnonymousAuthenticationFilter并不需要,但是通常情况下会使用它,因为只对请求添加了一点的预处理。你可能并不认识这个 过 滤 器 , 除 了 我 们 在 第 二 章 对 其 简 短 提 到 以 外 。 这 是 因 为 对 于AnonymousAuthenticationFilter的配置都掩盖在security命名空间之中。
列出的这两个属性都是需要的。userAttribute 属性声明了为匿名用户提供的用户名和GrantedAuthority。用户名和GrantedAuthority可能在我们的应用中用来验证用户是不是匿名用户。Key 可 能 是 随 机 生 成 的 , 但 是 需 要 在 一 个 bean 中 使 用(o.s.s.authentication.AnonymousAuthenticationProvider),我们稍后将会进行配置。
"
[html] view plaincopy
  1. <bean id="filterSecurityInterceptor"  
  2.           class="org.springframework.security.web.access.intercept.FilterSecurityInterceptor">  
  3.           <property name="authenticationManager" ref="customAuthenticationManager" />  
  4.           <property name="accessDecisionManager" ref="affirmativeBased" />  
  5.           <property name="securityMetadataSource">  
  6.                <security:filter-security-metadata-source>  
  7.                     <security:intercept-url pattern="/login.do" access="IS_AUTHENTICATED_ANONYMOUSLY" />  
  8.                     <security:intercept-url pattern="/home.do" access="IS_AUTHENTICATED_ANONYMOUSLY" />  
  9.                     <security:intercept-url pattern="/account/*.do" access="ROLE_USER" />  
  10.                     <security:intercept-url pattern="/*" access="ROLE_USER" />  
  11.                </security:filter-security-metadata-source>  
  12.           </property>  
  13. </bean>  

  在我们基本处理过滤器链的最后一个是最终负责检查Authentication的,而这是前面已配置的安全过滤器的处理结果。正是这个过滤器确定一个特定的请求最终是被拒绝还是被接受。 

再建立一些bean去辅助完成上边的功能:

[html] view plaincopy
  1. <bean class="org.springframework.security.access.vote.AffirmativeBased"  
  2.          id="affirmativeBased">  
  3.          <property name="decisionVoters">  
  4.               <list>  
  5.                    <ref bean="roleVoter" />  
  6.                    <ref bean="authenticatedVoter" />  
  7.               </list>  
  8.          </property>  
  9.     </bean>  
  10.     <bean class="org.springframework.security.access.vote.RoleVoter"  
  11.          id="roleVoter" />  
  12.     <bean class="org.springframework.security.access.vote.AuthenticatedVoter"  
  13.          id="authenticatedVoter" />  
  14.   
  15.     <bean id="daoAuthenticationProvider"  
  16.          class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">  
  17.          <property name="userDetailsService" ref="jdbcUserService" />  
  18.     </bean>  
  19.     <bean id="anonymousAuthenticationProvider"  
  20.          class="org.springframework.security.authentication.AnonymousAuthenticationProvider">  
  21.          <property name="key" value="BF93JFJ091N00Q7HF" />  
  22.     </bean>  
  23.   
  24.     <bean id="customAuthenticationManager"  
  25.          class="org.springframework.security.authentication.ProviderManager">  
  26.          <property name="providers">  
  27.               <list>  
  28.                    <ref local="daoAuthenticationProvider" />  
  29.                    <ref local="anonymousAuthenticationProvider" />  
  30.               </list>  
  31.          </property>  
  32.     </bean>  

然后看到这里,我决定自己写一个连接mysql的spring security自定义例子。
[html] view plaincopy
  1. <!-- 定义UserDetailsService -->  
  2.      <bean id="jdbcUserService" class="org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl">  
  3.           <property name="dataSource" ref="dataSource" />  
  4.      </bean>  
  5.       
  6.      <!-- 定义数据库源连接池 -->  
  7.      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
  8.         <property name="driverClassName" value="${jdbc.driver}"/>  
  9.         <property name="url" value="${jdbc.url}"/>  
  10.         <property name="username" value="${jdbc.username}"/>  
  11.         <property name="password" value="${jdbc.password}"/>  
  12.     </bean>  

这样就可以连接我们自己的mysql数据库了。

连接数据库以后,我继续研究这本书中写的知识点,发现突然又跳到了Session生命周期,估计后边肯定能用到,所以我就也跟着看了:
pring Security有很多地方影响用户的HttpSession的生命周期。有很多功能只有将相关类配置成Spring  bean时才可用。以下的表格列出了能够影响session创建和销毁的bean属性:


我们了解这些知识以后,重新进行过滤器链的配置:

[html] view plaincopy
  1. <!-- 配置一个定义的过滤器链 -->  
  2.      <bean id="springSecurityFilterChain" class="org.springframework.security.web.FilterChainProxy">  
  3.           <security:filter-chain-map path-type="ant">  
  4.                <security:filter-chain pattern="/**"  
  5.                     filters="  
  6.                           securityContextPersistenceFilter,  
  7.                          logoutFilter,  
  8.                          usernamePasswordAuthenticationFilter,  
  9.                          rememberMeAuthenticationFilter,  
  10.                          anonymousAuthenticationFilter,  
  11.                          exceptionTranslationFilter,  
  12.                          filterSecurityInterceptor" />  
  13.           </security:filter-chain-map>  
  14. </bean>  

配置一些这里我们还没有写的过滤器。

[html] view plaincopy
  1. <!-- 配置退出的过滤器信息 -->  
  2.      <bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">  
  3.           <!-- 用户退出要转向的url -->  
  4.           <constructor-arg value="/" />  
  5.           <constructor-arg>  
  6.                <array>  
  7.                     <ref local="logoutHandler" />  
  8.                </array>  
  9.           </constructor-arg>  
  10.           <!-- 要拦截的退出过请求url -->  
  11.           <property name="filterProcessesUrl" value="/logout" />  
  12.      </bean>  
  13.      <!-- 用于处理登陆退出的处理类 -->  
  14.      <bean id="logoutHandler" class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler"/>  

,接下来又配置了记住密码过滤器:
[html] view plaincopy
  1. <!-- 配置记住密码的过滤器 -->  
  2.      <bean id="rememberMeAuthenticationFilter"  
  3.           class="org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter">  
  4.           <property name="rememberMeServices" ref="rememberMeServices" />  
  5.           <property name="authenticationManager" ref="customAuthenticationManager" />  
  6.      </bean>  
  7.      <!-- 定义记住密码的服务类 -->  
  8.      <bean id="rememberMeServices"  
  9.           class="org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices">  
  10.           <property name="key" value="jbcpPetStore" />  
  11.           <property name="tokenValiditySeconds" value="3600" />  
  12.           <property name="tokenRepository" ref="jdbcRememberMeTokenRepository" />  
  13.           <property name="userDetailsService" ref="jdbcUserService" />  
  14.      </bean>  
  15.      <!-- 配置rememberme的token存储 -->  
  16.      <bean id="jdbcRememberMeTokenRepository"  
  17.           class="org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl">  
  18.           <property name="dataSource" ref="dataSource" />  
  19.      </bean>  
  20.      <!-- 配置记住密码的认证提供者 -->  
  21.      <bean id="rememberMeAuthenticationProvider"  
  22.           class="org.springframework.security.authentication.RememberMeAuthenticationProvider">  
  23.           <property name="key" value="jbcpPetStore" />  
  24.      </bean>  

因为rememberme是有一个认证提供者,所以我们需要把它加入认证管理器中:

[html] view plaincopy
  1. <!-- 自定义的管理器 -->  
  2.      <bean id="customAuthenticationManager"  
  3.           class="org.springframework.security.authentication.ProviderManager">  
  4.           <property name="providers">  
  5.                <list>  
  6.                     <ref local="daoAuthenticationProvider" />  
  7.                     <ref local="anonymousAuthenticationProvider" />  
  8.                     <ref local="rememberMeAuthenticationProvider"/>  
  9.                </list>  
  10.           </property>  
  11.      </bean>  

那好,加入这个以后,我们知道,当用户登陆时也会判断是否已经记住密码,所以在验证时也会进行判断:
[html] view plaincopy
  1. <!-- 监听表单登陆的验证请求 -->  
  2.      <bean id="usernamePasswordAuthenticationFilter"  
  3.           class="org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">  
  4.           <property name="authenticationManager" ref="customAuthenticationManager" />  
  5.           <property name="rememberMeServices" ref="rememberMeServices"/>  
  6.      </bean>  

还有一步,就是当我们退出时,我们需要在退出中调用我们的记住密码服务,进而进行退出登陆:

[html] view plaincopy
  1. <!-- 配置退出的过滤器信息 -->  
  2.      <bean id="logoutFilter"  
  3.           class="org.springframework.security.web.authentication.logout.LogoutFilter">  
  4.           <!-- 用户退出要转向的url -->  
  5.           <constructor-arg value="/" />  
  6.           <constructor-arg>  
  7.                <array>  
  8.                     <ref local="logoutHandler" />  
  9.                     <ref local="rememberMeServices"/>  
  10.                </array>  
  11.           </constructor-arg>  
  12.           <!-- 要拦截的退出过请求url -->  
  13.           <property name="filterProcessesUrl" value="/logout" />  
  14.      </bean>  

还有一个过滤器要配置,就是我们的异常过滤器(ExceptionTranslationFilter):
[html] view plaincopy
  1. <!-- 配置异常过滤器 -->  
  2.      <bean id="exceptionTranslationFilter"  
  3.           class="org.springframework.security.web.access.ExceptionTranslationFilter">  
  4.           <property name="authenticationEntryPoint" ref="authenticationEntryPoint" />  
  5.           <property name="accessDeniedHandler" ref="accessDeniedHandler" />  
  6.      </bean>  
  7.      <!-- 配置认证进入点 -->  
  8.      <bean id="authenticationEntryPoint"  
  9.           class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">  
  10.           <property name="loginFormUrl" value="/login.html" />  
  11.      </bean>  
  12.      <!-- 配置连接拒绝处理器 -->  
  13.      <bean id="accessDeniedHandler"  
  14.           class="org.springframework.security.web .access.AccessDeniedHandlerImpl">  
  15.           <property name="errorPage" value="/accessDenied.do" />  
  16.      </bean>  

终于配置完成了,咱们是可以把这个项目运行起来的,先不说这个,书中给了我们两个选择,一个是security命名空间,一个是明确的bean定义,那么如何选择呢:


。。 我整理了一下这个项目,现在是可以跑起来的,而且使用mysql进行了集成。 不用那个hsql了,我觉得看起来可能会好一点。

下载地址:http://download.csdn.net/detail/dulei294948/6312707
0 0
原创粉丝点击