首先我們?yōu)?Spring Security 專門建立一個 Spring 的配置文件,該文件就專門用來作為 Spring Security 的配置。使用 Spring Security 我們需要引入 Spring Security 的 NameSpace。
<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 命名空間的引入可以簡化我們的開發(fā),它涵蓋了大部分 Spring Security 常用的功能。它的設(shè)計(jì)是基于框架內(nèi)大范圍的依賴的,可以被劃分為以下幾塊。
引入了 Spring Security 的 NameSpace 之后我們就可以使用該命名空間下的元素來配置 Spring Security 了。首先我們來定義一個 http 元素,security 只是我們使用命名空間的一個前綴。http 元素是用于定義 Web 相關(guān)權(quán)限控制的。
<security:http auto-config="true">
<security:intercept-url pattern="/**" access="ROLE_USER"/>
</security:http>
如上定義中,intercept-url 定義了一個權(quán)限控制的規(guī)則。pattern 屬性表示我們將對哪些 url 進(jìn)行權(quán)限控制,其也可以是一個正則表達(dá)式,如上的寫法表示我們將對所有的 URL 進(jìn)行權(quán)限控制;access 屬性表示在請求對應(yīng)的 URL 時需要什么權(quán)限,默認(rèn)配置時它應(yīng)該是一個以逗號分隔的角色列表,請求的用戶只需擁有其中的一個角色就能成功訪問對應(yīng)的 URL。這里的 “ROLE_USER” 表示請求的用戶應(yīng)當(dāng)具有 ROLEUSER 角色?!癛OLE” 前綴是一個提示 Spring 使用基于角色的檢查的標(biāo)記。
有了權(quán)限控制的規(guī)則了后,接下來我們需要定義一個 AuthenticationManager 用于認(rèn)證。我們先來看如下定義:
<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(對應(yīng) authentication-provider 元素)來進(jìn)行真正的認(rèn)證,默認(rèn)情況下 authentication-provider 對應(yīng)一個 DaoAuthenticationProvider,其需要 UserDetailsService(對應(yīng) user-service 元素)來獲取用戶信息 UserDetails(對應(yīng) user 元素)。這里我們只是簡單的使用 user 元素來定義用戶,而實(shí)際應(yīng)用中這些信息通常都是需要從數(shù)據(jù)庫等地方獲取的,這個將放到后續(xù)再講。我們可以看到通過 user 元素我們可以指定 user 對應(yīng)的用戶名、密碼和擁有的權(quán)限。user-service 還支持通過 properties 文件來指定用戶信息,如:
<security:user-service properties="/WEB-INF/config/users.properties"/>
其中屬性文件應(yīng)遵循如下格式:
username=password,grantedAuthority[,grantedAuthority][,enabled|disabled]
所以,對應(yīng)上面的配置文件,我們的 users.properties 文件的內(nèi)容應(yīng)該如下所示:
#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 的初始配置文件,也可以在對應(yīng) 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 的配置文件是通過對應(yīng)的 ContextLoaderListener 來加載和初始化的,上述代碼中的 applicationContext.xml 文件就是對應(yīng)的 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>
接下來可以啟動我們的應(yīng)用,然后在瀏覽器中訪問我們的主頁。你會看到如下頁面。
因?yàn)槲覀兊?spring-security.xml 文件中配置好了所有的請求都需要 “ROLE_USER” 權(quán)限,所以當(dāng)我們在請求主頁的時候,Spring Security 發(fā)現(xiàn)我們還沒有登錄,Spring 會引導(dǎo)我們到登錄界面。使用正確的用戶名和密碼(如上面配置的 user/user 或 admin/admin)登錄后,如果符合對應(yīng)的權(quán)限我們就可以訪問主頁了,否則將出現(xiàn) 403(禁止訪問)界面。
可能你會奇怪,我們沒有建立上面的登錄頁面,為什么 Spring Security 會跳到上面的登錄頁面呢?這是我們設(shè)置 http 的 auto-config=”true” 時 Spring Security 自動為我們生成的。
當(dāng)指定 http 元素的 auto-config=”true” 時,就相當(dāng)于如下內(nèi)容的簡寫。
<security:http>
<security:form-login/>
<security:http-basic/>
<security:logout/>
</security:http>
這些元素負(fù)責(zé)建立表單登錄、基本的認(rèn)證和登出處理。它們都可以通過指定對應(yīng)的屬性來改變它們的行為。
更多建議: