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