新的安全問(wèn)題不斷出現(xiàn),Spring Security也必須不斷升級(jí)。作為一個(gè)主版本號(hào)修改的發(fā)行版本,Spring Security團(tuán)隊(duì)有機(jī)會(huì)來(lái)做一些主動(dòng)的改變:
Spring Security支持更多的默認(rèn)安全行為
最小化信息泄露
移除不建議使用的API
要更詳細(xì)的查看如果從3.x升級(jí)到4.x,請(qǐng)參考:
Migrating from Spring Security 3.x to 4.x (XML Configuration)
Migrating from Spring Security 3.x to 4.x (Java Configuration)
筆者注:跟傳統(tǒng)情況下,我們?cè)谧鲞^(guò)濾器中做權(quán)限驗(yàn)證類似,Spring Secuirty也是在Filter中進(jìn)行權(quán)限驗(yàn)證。因此使用Java代碼配置Spring Security主要是這兩個(gè)步驟:
1、創(chuàng)建過(guò)濾器
2、注冊(cè)過(guò)濾器。
關(guān)于創(chuàng)建過(guò)濾器與注冊(cè)過(guò)濾器過(guò)程中內(nèi)部都做了什么,我們?cè)诤竺鏁?huì)詳細(xì)解釋,目前我們只是要知道如何配置。
第一步:創(chuàng)建過(guò)濾器
第一步,是使用Java代碼創(chuàng)建Spring Security的配置。這段配置創(chuàng)建一個(gè)Servlet Filter:springSecurityFilterChain,其負(fù)責(zé)應(yīng)用中的所有安全,包括:保護(hù)應(yīng)用的URLS,驗(yàn)證提交的username和password,重定向到登錄頁(yè)面等。
編寫一個(gè)類,名字隨意,這里為起名為SecurityConfig,源碼如下所示:
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import?org.springframework.security.config.annotation.web.builders.HttpSecurity;
import?org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import?org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@EnableWebSecurity
public?class?SecurityConfig?extends?WebSecurityConfigurerAdapter{
@Autowired
public?void?configureGlobal(AuthenticationManagerBuilder?auth)?throws?Exception?{
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
}
方法名 configureGlobal是無(wú)關(guān)緊要的,重要的是在一個(gè)添加了@EnableWebSecurity,@EnableGlobalMethodSecurity或者@EnableGlobalAuthentication注解的類里面,注入?AuthenticationManagerBuilder。
這段代碼內(nèi)容很少,但事實(shí)上已經(jīng)做了很多的默認(rèn)安全驗(yàn)證,包括:
1、訪問(wèn)應(yīng)用中的每個(gè)URL都需要進(jìn)行驗(yàn)證
2、生成一個(gè)登陸表單
3、允許用戶使用username和password來(lái)登陸
4、允許用戶注銷
5、CSRF攻擊攔截
6、 Session Fixation攻擊
7、 安全Header集成
* HTTP Strict Transport Security for secure requests
* X-Content-Type-Options integration
* 緩存控制 (can be overridden later by your application to allow caching of your static resources)
* X-XSS-Protection integration
* X-Frame-Options integration to help prevent Clickjacking
Integrate with the following Servlet API methods
* HttpServletRequest#getRemoteUser()
* HttpServletRequest.html#getUserPrincipal()
* HttpServletRequest.html#isUserInRole(java.lang.String)
* HttpServletRequest.html#login(java.lang.String, java.lang.String)
* HttpServletRequest.html#logout()
第二步:注冊(cè)過(guò)濾器
下一步是注冊(cè)springSecurityFilterChain。這個(gè)可以借助Spring3.1引入的WebApplicationInitializer完成。SpringSecurity提供了一個(gè)基類AbstractSecurityWebApplicationInitializer來(lái)確保?springSecurityFilterChain被注冊(cè)。對(duì)于如何使用AbstractSecurityWebApplicationInitializer, 這要依據(jù)Spring Secuirty是否項(xiàng)目中的唯一的Spring組件而有所不同。
項(xiàng)目中沒(méi)有使用Spring
如果你沒(méi)有使用Spring或者SpringMvc,你需要傳遞我們的?SecurityConfig類到父類中,從而確保我們的配置會(huì)被加載??梢詤⒄找幌碌拇a:
import?org.springframework.security.web.context.*;
public?class?SecurityWebApplicationInitializer
????????extends?AbstractSecurityWebApplicationInitializer?{
????????public?SecurityWebApplicationInitializer()?{
????????????????super(SecurityConfig.class);
????????}
}
SecurityWebApplicationInitializer將會(huì)做以下的事情:
自動(dòng)注冊(cè) springSecurityFilterChain 過(guò)濾器,并作用于應(yīng)用中的每個(gè)URL。
添加一個(gè) ContextLoaderListener 來(lái)加載 SecurityConfig類。
項(xiàng)目中已經(jīng)使用了SpringMvc
如果在我們的應(yīng)用程序中已經(jīng)使用了Spring,那么在我們的應(yīng)用中可能已經(jīng)有了一個(gè)WebApplicationInitializer來(lái)加載我們的配置,如果我們還使用之前的代碼,將會(huì)出現(xiàn)一個(gè)錯(cuò)誤。此時(shí)我們應(yīng)該在已經(jīng)存在的ApplicationContext中注冊(cè)Spring Security。例如,如果我們已經(jīng)使用SpringMvc,那么我們的代碼應(yīng)該是如下所示:
import?org.springframework.security.web.context.*;
public?class?SecurityWebApplicationInitializer
????????extends?AbstractSecurityWebApplicationInitializer?{
}
這段代碼僅僅會(huì)將 springSecurityFilterChain 注冊(cè)到應(yīng)用中,并作用于每個(gè)url。此時(shí)我們的SecurityConfig類依然會(huì)被已經(jīng)存在的 ApplicationInitializer 加載。例如,我們使用SpringMvc,它將會(huì)被添加到getRootConfigClasses()。
public?class?MvcWebApplicationInitializer?extends
????????????????AbstractAnnotationConfigDispatcherServletInitializer?{
//Specify?@Configuration?and/or?@Component?classes?to?be?provided?to?the?root?application?context.
????????@Override
????????protected?Class<?>[]?getRootConfigClasses()?{
????????????????return?new?Class[]?{?SecurityConfig.class?};
????????}
????????//?...?other?overrides?...
}
運(yùn)行項(xiàng)目
將以上代碼部署到Tomcat中運(yùn)行,通過(guò)瀏覽器訪問(wèn)任何頁(yè)面都會(huì)被重新定位到一個(gè)登陸頁(yè)面,截圖如下:
?
這個(gè)頁(yè)面是Spring Security自動(dòng)幫我們生成的。我們可以使用之前配置的用戶名和密碼進(jìn)行登錄。自動(dòng)生成這個(gè)頁(yè)面的代碼位于類DefaultLoginPageGeneratingFilter的generateLoginPageHtml方法中。
免費(fèi)學(xué)習(xí)視頻歡迎關(guān)注云圖智聯(lián):https://e.yuntuzhilian.com/