spring源碼剖析之Spring Security安全框架

Spring Security是一個能夠爲基於Spring的企業應用系統提供聲明式的安全訪問控制解決方案的安全框架。它提供了一組可以在Spring應用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反轉Inversion of Control ,DI:Dependency Injection 依賴注入)和AOP(面向切面編程)功能,爲應用系統提供聲明式的安全訪問控制功能,減少了爲企業系統安全控制編寫大量重複代碼的工作。本站素文宅www.yoodb.com爲大家分析一下Spring Security安全框架,僅供大家參考學習。

安全框架Spring Security具體可以分爲如下Jar包:

spring-security-acl-3.1.4.RELEASE.jar
spring-security-aspects-3.1.4.RELEASE.jar
spring-security-cas-3.1.4.RELEASE.jar
spring-security-config-3.1.4.RELEASE.jar
spring-security-core-3.1.4.RELEASE.jar
spring-security-crypto-3.1.4.RELEASE.jar
spring-security-ldap-3.1.4.RELEASE.jar
spring-security-openid-3.1.4.RELEASE.jar
spring-security-remoting-3.1.4.RELEASE.jar
spring-security-taglibs-3.1.4.RELEASE.jar
spring-security-web-3.1.4.RELEASE.jar

使用Spring Security需要引入Spring Security的NameSpace命名空間,具體xml信息如下:

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:security="http://www.springframework.org/schema/security"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.1.xsd">

</beans>

Spring Security命名空間的引入可以簡化我們的開發,它涵蓋了大部分Spring Security常用的功能。它的設計是基於框架內大範圍的依賴的,可以被劃分爲以下幾塊。 Web/Http 安全:這是最複雜的部分。通過建立filter和相關的service bean來實現框架的認證機制。當訪問受保護的URL時會將用戶引入登錄界面或者是錯誤提示界面。 業務對象或者方法的安全:控制方法訪問權限的。 AuthenticationManager:處理來自於框架其他部分的認證請求。 AccessDecisionManager:爲Web或方法的安全提供訪問決策。會註冊一個默認的,但是我們也可以通過普通bean註冊的方式使用自定義的AccessDecisionManager。 AuthenticationProvider:AuthenticationManager是通過它來認證用戶的。 UserDetailsService:跟AuthenticationProvider關係密切,用來獲取用戶信息的。

引入了Spring Security的NameSpace之後我們就可以使用該命名空間下的元素來配置Spring Security了。首先我們來定義一個http元素,security只是我們使用命名空間的一個前綴。http元素是用於定義Web相關權限控制的。

   <security:http auto-config="true">
      <security:intercept-url pattern="/**" access="ROLE_USER"/>
   </security:http>

如上定義中,intercept-url定義了一個權限控制的規則。pattern屬性表示我們將對哪些url進行權限控制,其也可以是一個正則表達式,如上的寫法表示我們將對所有的URL進行權限控制;access屬性表示在請求對應的URL時需要什麼權限,默認配置時它應該是一個以逗號分隔的角色列表,請求的用戶只需擁有其中的一個角色就能成功訪問對應的URL。這裏的“ROLEUSER”表示請求的用戶應當具有ROLE_USER角色。“ROLE”前綴是一個提示Spring使用基於角色的檢查的標記。來源:http://www.yoodb.com/article/display/1219 有了權限控制的規則了後,接下來我們需要定義一個AuthenticationManager用於認證。我們先來看如下定義:

<security:authentication-manager>
      <security:authentication-provider>
         <security:user-service>
            <security:user name="user" password="user" authorities="ROLE_USER"/>
            <security:user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN"/>
         </security:user-service>
      </security:authentication-provider>
   </security:authentication-manager>

authentication-manager元素指定了一個AuthenticationManager,其需要一個AuthenticationProvider(對應authentication-provider元素)來進行真正的認證,默認情況下authentication-provider對應一個DaoAuthenticationProvider,其需要UserDetailsService(對應user-service元素)來獲取用戶信息UserDetails(對應user元素)。

這裏我們只是簡單的使用user元素來定義用戶,而實際應用中這些信息通常都是需要從數據庫等地方獲取的,這個將放到後續再講。我們可以看到通過user元素我們可以指定user對應的用戶名、密碼和擁有的權限。user-service還支持通過properties文件來指定用戶信息,如:

<security:user-service properties="/WEB-INF/config/users.properties"/> 其中屬性文件應遵循如下格式: username=password,grantedAuthority[,grantedAuthority][,enabled|disabled] 所以,對應上面的配置文件,我們的users.properties文件的內容應該如下所示:

#username=password,grantedAuthority[,grantedAuthority][,enabled|disabled]
user=user,ROLE_USER
admin=admin,ROLE_USER,ROLE_ADMIN

至此,我們的Spring Security配置文件的配置就完成了。完整配置文件將如下所示。

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:security="http://www.springframework.org/schema/security"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.1.xsd">

   <security:http auto-config="true">
      <security:intercept-url pattern="/**" access="ROLE_USER"/>
   </security:http>    

   <security:authentication-manager>
      <security:authentication-provider>
         <security:user-service>
            <security:user name="user" password="user" authorities="ROLE_USER"/>
            <security:user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN"/>
         </security:user-service>
      </security:authentication-provider>
   </security:authentication-manager>

</beans>

之後我們告訴Spring加載這個配置文件。通常,我們可以在web.xml文件中通過context-param把它指定爲Spring的初始配置文件,也可以在對應Spring的初始配置文件中引入它。這裏我們採用前者。

<context-param>
      <param-name>contextConfigLocation</param-name>
   <param-value>/WEB-INF/config/applicationContext.xml,/WEB-INF/config/spring-security.xml</param-value>
   </context-param>

   <listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
   </listener>

Spring的配置文件是通過對應的ContextLoaderListener來加載和初始化的,上述代碼中的applicationContext.xml文件就是對應的Spring的配置文件,如果沒有可以不用配置。接下來我們還需要在web.xml中定義一個filter用來攔截需要交給Spring Security處理的請求,需要注意的是該filter一定要定義在其它如SpringMVC等攔截請求之前。這裏我們將攔截所有的請求,具體做法如下所示:

 <filter>
      <filter-name>springSecurityFilterChain</filter-name>
     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
   </filter>
   <filter-mapping>
      <filter-name>springSecurityFilterChain</filter-name>
      <url-pattern>/*</url-pattern>
 </filter-mapping>
發佈了39 篇原創文章 · 獲贊 48 · 訪問量 15萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章