君子博学而日参省乎己 则知明而行无过矣

博客园 首页 新随笔 联系 订阅 管理
转自 http://mislay.iteye.com/blog/411323 

 

1.spring security初体验

applicationContext.xml

Xml代码  收藏代码
  1. <beans:beans   
  2.  xmlns="http://www.springframework.org/schema/security"  
  3.    xmlns:beans="http://www.springframework.org/schema/beans"  
  4.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
  6.                        http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd">  
  7.                 
  8.      <http auto-config='true'>  
  9.       <intercept-url pattern="/**" access="ROLE_USER" />  
  10.    </http>  
  11.       
  12.     <authentication-provider>  
  13.   <user-service>  
  14.   <user name="jimi" password="jimispassword" authorities="ROLE_USER, ROLE_ADMIN" />  
  15.   <user name="bob" password="bobspassword" authorities="ROLE_USER" />  
  16.   </user-service>  
  17.  </authentication-provider>   
  18. </beans:beans>  

 

web.xml配置文件

Xml代码  收藏代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <web-app version="2.4"   
  3.  xmlns="http://java.sun.com/xml/ns/j2ee"   
  4.  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
  5.  xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee   
  6.  http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">  
  7.    
  8.  <filter>  
  9.   <filter-name>springSecurityFilterChain</filter-name>  
  10.   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>  
  11.  </filter>  
  12.    
  13.  <filter-mapping>  
  14.   <filter-name>springSecurityFilterChain</filter-name>  
  15.   <url-pattern>/*</url-pattern>  
  16.  </filter-mapping>  
  17.    
  18.  <listener>  
  19.   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  20.  </listener>  
  21.  <context-param>     
  22.        <param-name>contextConfigLocation</param-name>     
  23.        <!-- <param-value>classpath*:applicationContext.xml</param-value> -->  
  24.        <param-value>/WEB-INF/applicationContext.xml</param-value>  
  25.     </context-param>  
  26.      
  27.      
  28.  <welcome-file-list>  
  29.      <welcome-file>index.jsp</welcome-file>  
  30.  </welcome-file-list>  
  31. </web-app>  

 
auto-config属性其实是<form-login/>,<http-basic/>,<logout/>的缩写.
没配置登录页面的情况下,spring自动生成一个.


2.指定自己的登录页面以及跳转规则

Xml代码  收藏代码
  1. <http>  
  2.     <intercept-url pattern='/login.htm*' filters='none'/>  
  3.     <intercept-url pattern='/**' access='ROLE_USER' />  
  4.     <form-login login-page='/login.htm' default-target-url='/home.htm' always-use-default-target='true' />  
  5. </http>  

 

<intercept-url pattern='/login.htm*' filters='none'/>这个标签是把验证排除在外。因为这是一个登录页面。
而form-login标签的login-page则指定遇到受限资源需要进行登录时候的页面.
default-target-url指定了从登录页面登录后进行跳转的页面
always-use-default-target这个属性表示登录成功后强制跳转到default-target-url这个地址。默认情况下如果是从首先页面过来登录的,那么跳转是跳转回受限页面。

 

3.其他的验证方式.


    LDAP验证

Xml代码  收藏代码
  1. <authentication-provider user-service-ref='myUserDetailsService'/>  

 

   DATABASE验证

Xml代码  收藏代码
  1. <authentication-provider>  
  2.     <jdbc-user-service data-source-ref="securityDataSource"/>  
  3. </authentication-provider>  

 

或者

Xml代码  收藏代码
  1. <authentication-provider user-service-ref='myUserDetailsService'/>  
  2.   
  3. <beans:bean id="myUserDetailsService" class="org.springframework.security.userdetails.jdbc.JdbcDaoImpl">  
  4.     <beans:property name="dataSource" ref="dataSource"/>  
  5. </beans:bean>  

 

4.密码的编码器配置

 

Xml代码  收藏代码
  1. <authentication-provider>  
  2.   <password-encoder hash="sha"/>  
  3.   <user-service>  
  4.     <user name="jimi" password="d7e6351eaa13189a5a3641bab846c8e8c69ba39f" authorities="ROLE_USER, ROLE_ADMIN" />  
  5.     <user name="bob" password="4e7421b1b8765d8f9406d87e7cc6aa784c4ab97f" authorities="ROLE_USER" />  
  6.   </user-service>  
  7. </authentication-provider>  

 


另外还以为密码配置种子(盐值)

Xml代码  收藏代码
  1. <password-encoder hash="sha">  
  2.   <salt-source user-property="username"/>  
  3. </password-encoder>  

 

还可以通过password-encoder的ref属性,指定一个自定义的密码编码器bean。 这应该包含application context中一个bean的名字,它应该是Spring Security的PasswordEncoder接口的一个实例。

 

5.对HTPPS的处理

 

Xml代码  收藏代码
  1. <http>  
  2.     <intercept-url pattern="/secure/**" access="ROLE_USER" requires-channel="https"/>  
  3.     <intercept-url pattern="/**" access="ROLE_USER" requires-channel="any"/>  
  4.     ...  
  5. </http>  

 

当用户用http访问需要https的访问验证时可以通过requires-channel属性来进行跳转.
requires-channel共有三个值:http,https,any。 any表示http和https都可以。

如果使用了非默认的http和https的端口号,那么添加port-mappings即可

Xml代码  收藏代码
  1. <http>  
  2.     ...  
  3.     <port-mappings>  
  4.       <port-mapping http="9080" https="9443"/>  
  5.     </port-mappings>  
  6. </http>  

 

 

6.限制用户的登录(单次登录)


在web.xml中添加监听器

Xml代码  收藏代码
  1. <listener>  
  2.   <listener-class>org.springframework.security.ui.session.HttpSessionEventPublisher</listener-class>  
  3. </listener>  

 

然后再配spring置中添加

Xml代码  收藏代码
  1. <http>  
  2.     ...  
  3.     <concurrent-session-control max-sessions="1" />  
  4. </http>  

 
这种做法是在第二次登陆时,第一登录就失效了。

如果想禁止第二次登陆,那么可以设置exception-if-maximum-exceeded.

Xml代码  收藏代码
  1. <http>  
  2.    ...  
  3.    <concurrent-session-control max-sessions="1" exception-if-maximum-exceeded="true"/>  
  4.  </http>  

 

字面上不难理解,第二次登陆就抛出异常,这样就防止了重复登录

 

7.OpenID登录


命名空间支持OpenID登录,替代普通的表单登录,或作为一种附加功能,只需要进行简单的修改:

  

Xml代码  收藏代码
  1. <http>  
  2.     <intercept-url pattern="/**" access="ROLE_USER" />  
  3.     <openid-login />  
  4.   </http>  

   
你应该注册一个OpenID供应器(比如myopenid.com),然后把用户信息添加到你的内存<user-service>中:

  <user name="http://jimi.hendrix.myopenid.com/" password="notused" authorities="ROLE_USER" />
  
你应该可以使用myopenid.com网站登录来进行验证了。

 

8.添加自己的过滤器


添加你自己的filter
如果你以前使用过Spring Security,你就应该知道这个框架里维护了一个过滤器链,来提供服务。 你也许想把你自己的过滤器添加到链条的特定位置,或者使用一个Spring Security的过滤器,这个过滤器现在还没有在命名空间配置中进行支持(比如CAS)。 或者你想要使用一个特定版本的标准命名空间过滤器,比如<form-login>创建的AuthenticationProcessingFilter,从而获得一些额外的配置选项的优势,这些可以通过直接配置bean获得。 你如何在命名空间配置里实现这些功能呢?过滤器链现在已经不能直接看到了。

 

过滤器顺序在使用命名空间的时候是被严格执行的。 每个Spring Security过滤器都实现了Spring的Ordered接口,这些通过命名空间穿件的过滤器在初始化的时候就预先被排好序了。 标准的过滤器在命名空间里都有自己的假名,有关创建过滤器的过滤器,假名和命名空间元素,属性可以在Table 2.1, “标准过滤器假名和顺序”中找到。

假名过滤器累命名空间元素或属性
CHANNEL_FILTERChannelProcessingFilterhttp/intercept-url
CONCURRENT_SESSION_FILTERConcurrentSessionFilterhttp/concurrent-session-control 
SESSION_CONTEXT_INTEGRATION_FILTERHttpSessionContextIntegrationFilterhttp
LOGOUT_FILTERLogoutFilterhttp/logout
X509_FILTERX509PreAuthenticatedProcessigFilterhttp/x509
PRE_AUTH_FILTERAstractPreAuthenticatedProcessingFilterSubclasses N/A
CAS_PROCESSING_FILTER CasProcessingFilter N/A
AUTHENTICATION_PROCESSING_FILTERAuthenticationProcessingFilterhttp/form-login
BASIC_PROCESSING_FILTERBasicProcessingFilterhttp/http-basic 
SERVLET_API_SUPPORT_FILTERSecurityContextHolderAwareRequestFilterhttp/@servlet-api-provision 
REMEMBER_ME_FILTER RememberMeProcessingFilterhttp/remember-me
ANONYMOUS_FILTER AnonymousProcessingFilterhttp/anonymous
EXCEPTION_TRANSLATION_FILTER ExceptionTranslationFilterhttp
NTLM_FILTERNtlmProcessingFilterN/A
FILTER_SECURITY_INTERCEPTORFilterSecurityInterceptor

http

 

 

SWITCH_USER_FILTER     SwitchUserProcessingFilter    N/A


你可以把你自己的过滤器添加到队列中,使用custom-filter元素,使用这些名字中的一个,来指定你的过滤器应该出现的位置:

 

Xml代码  收藏代码
  1. <beans:bean id="myFilter" class="com.mycompany.MySpecialAuthenticationFilter">  
  2.    <custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>  
  3.  </beans:bean>  

   
你还可以使用after 或 before属性,如果你想把你的过滤器添加到队列中另一个过滤器的前面或后面。 可以分别在position属性使用"FIRST" 或 "LAST"来指定你想让你的过滤器出现在队列元素的前面或后面。

避免过滤器位置发生冲突
如果你插入了一个自定义的过滤器,而这个过滤器可能与命名空间自己创建的标准过滤器放在同一个位置上,这样首要的是你不要错误包含命名空间的版本信息。 避免使用auto-config属性,然后删除所有会创建你希望替换的过滤器的元素。

注意,你不能替换那些<http>元素自己使用而创建出的过滤器,比如HttpSessionContextIntegrationFilter, ExceptionTranslationFilter 或 FilterSecurityInterceptor。

如果你替换了一个命名空间的过滤器,而这个过滤器需要一个验证入口点(比如,认证过程是通过一个未通过验证的用户访问受保护资源的尝试来触发的),你将也需要添加一个自定义的入口点bean。


9.防止session固定攻击。


<http>中的session-fixation-protection属性配置可以防止这种攻击。
它有三个选项:
a.migrateSession - 创建一个新session,把原来session中所有属性复制到新session中。这是默认值。
b.none - 什么也不做,继续使用原来的session。
c.newSession - 创建一个新的“干净的”session,不会复制session中的数据。


10.方法的保护


a.

Xml代码  收藏代码
  1. <global-method-security secured-annotations="enabled" jsr250-annotations="enabled"/>  

 
这个标签用于开启Spring Security的@Secured和JSR-250注解功能

Java代码  收藏代码
  1. public interface BankService {  
  2.   
  3.     @Secured("IS_AUTHENTICATED_ANONYMOUSLY")  
  4.     public Account readAccount(Long id);  
  5.   
  6.     @Secured("IS_AUTHENTICATED_ANONYMOUSLY")  
  7.     public Account[] findAccounts();  
  8.   
  9.     @Secured("ROLE_TELLER")  
  10.     public Account post(Account account, double amount);  
  11. }  

 

b.使用protect-pointcut来添加安全切点

Xml代码  收藏代码
  1. <global-method-security>  
  2.     <protect-pointcut expression="execution(* com.mycompany.*Service.*(..))" access="ROLE_USER"/>  
  3. </global-method-security>  

 

c.使用intercept-methods来构建安全方法

Xml代码  收藏代码
  1. <bean:bean id="target" class="com.mycompany.myapp.MyBean">  
  2.     <intercept-methods>  
  3.         <protect method="set*" access="ROLE_ADMIN" />  
  4.         <protect method="get*" access="ROLE_ADMIN,ROLE_USER" />  
  5.         <protect method="doSomething" access="ROLE_USER" />  
  6.     </intercept-methods>  
  7. </bean:bean>  

 
11.自定义的AccessDecisionManager


 方法安全的配置
  

Xml代码  收藏代码
  1. <global-method-security access-decision-manager-ref="myAccessDecisionManagerBean">  
  2.     ...  
  3.   </global-method-security>  

 
 web安全的配置
 

Xml代码  收藏代码
  1. <http access-decision-manager-ref="myAccessDecisionManagerBean">  
  2.     ...  
  3.   </http>  

 
12.默认的验证管理器


如果你在命名空间中使用了HTTP或方法安全,你不能使用自定义的AuthenticationManager.
ProviderManager注册另外的AuthenticationProvider bean,你可以使用<custom-authentication-provider>元素实现

Xml代码  收藏代码
  1. <bean id="casAuthenticationProvider"  
  2.       class="org.springframework.security.providers.cas.CasAuthenticationProvider">  
  3.     <security:custom-authentication-provider />  
  4.     ...  
  5. </bean>  

 

另一个常见的需求是,上下文中的另一个bean可能需要引用AuthenticationManager。 这里有一个特殊的元素,可以让你为AuthenticationManager注册一个别名,然后你可以application context的其他地方使用这个名字。

 

Xml代码  收藏代码
  1. <security:authentication-manager alias="authenticationManager"/>  
  2.   
  3.   <bean id="customizedFormLoginFilter" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">  
  4.      <security:custom-filter position="AUTHENTICATION_PROCESSING_FILTER"/>  
  5.      <property name="authenticationManager" ref="authenticationManager"/>  
  6.      ...  
  7.   </bean>  

 
13.从任意位置获取用户名密码等信息.

 

Java代码  收藏代码
  1. Object obj = SecurityContextHolder.getContext().getAuthentication().getPrincipal();  
  2.   
  3. if (obj instanceof UserDetails) {  
  4.   String username = ((UserDetails)obj).getUsername();  
  5. else {  
  6.   String username = obj.toString();  
  7. }  
posted on 2012-08-21 23:25  刺猬的温驯  阅读(2551)  评论(0编辑  收藏  举报