新的安全問題不斷出現,Spring Security也必須不斷升級。作為一個主版本號修改的發行版本,Spring Security團隊有機會來做一些主動的改變:
Spring Security支援更多的預設安全行為
最小化資訊洩露
移除不建議使用的API
要更詳細的檢視如果從3。x升級到4。x,請參考:
Migrating from Spring Security 3。x to 4。x (XML Configuration)
Migrating from Spring Security 3。x to 4。x (Java Configuration)
筆者注:跟傳統情況下,我們在做過濾器中做許可權驗證類似,Spring Secuirty也是在Filter中進行許可權驗證。因此使用Java程式碼配置Spring Security主要是這兩個步驟:
1、建立過濾器
2、註冊過濾器。
關於建立過濾器與註冊過濾器過程中內部都做了什麼,我們在後面會詳細解釋,目前我們只是要知道如何配置。
第一步:建立過濾器
第一步,是使用Java程式碼建立Spring Security的配置。這段配置建立一個Servlet Filter:
springSecurityFilterChain
,其負責應用中的所有安全,包括:保護應用的URLS,驗證提交的username和password,重定向到登入頁面等。
編寫一個類,名字隨意,這裡為起名為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是無關緊要的,重要的是在一個添加了 @EnableWebSecurity, @EnableGlobalMethodSecurity或者 @EnableGlobalAuthentication註解的類裡面,注入 AuthenticationManagerBuilder。
這段程式碼內容很少,但事實上已經做了很多的預設安全驗證,包括:
1、訪問應用中的每個URL都需要進行驗證
2、生成一個登陸表單
3、允許使用者使用username和password來登陸
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()
第二步:註冊過濾器
下一步是註冊springSecurityFilterChain。這個可以藉助Spring3。1引入的
WebApplicationInitializer
完成。SpringSecurity提供了一個基類
AbstractSecurityWebApplicationInitializer
來確保 springSecurityFilterChain被註冊。對於如何使用AbstractSecurityWebApplicationInitializer, 這要依據Spring Secuirty是否專案中的唯一的Spring元件而有所不同。
專案中沒有使用Spring
如果你沒有使用Spring或者SpringMvc,你需要傳遞我們的 SecurityConfig類到父類中,從而確保我們的配置會被載入。可以參照一下的程式碼:
import org。springframework。security。web。context。*;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
public SecurityWebApplicationInitializer() {
super(SecurityConfig。class);
}
}
SecurityWebApplicationInitializer將會做以下的事情:
自動註冊 springSecurityFilterChain 過濾器,並作用於應用中的每個URL。
新增一個 ContextLoaderListener 來載入 SecurityConfig類。
專案中已經使用了SpringMvc
如果在我們的應用程式中已經使用了Spring,那麼在我們的應用中可能已經有了一個 WebApplicationInitializer來載入我們的配置,如果我們還使用之前的程式碼,將會出現一個錯誤。此時我們應該在已經存在的ApplicationContext中註冊Spring Security。例如,如果我們已經使用SpringMvc,那麼我們的程式碼應該是如下所示:
import org。springframework。security。web。context。*;
public class SecurityWebApplicationInitializer
extends AbstractSecurityWebApplicationInitializer {
}
這段程式碼僅僅會將 springSecurityFilterChain 註冊到應用中,並作用於每個url。此時我們的SecurityConfig類依然會被已經存在的 ApplicationInitializer 載入。例如,我們使用SpringMvc,它將會被新增到 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 。。。
}
執行專案
將以上程式碼部署到Tomcat中執行,透過瀏覽器訪問任何頁面都會被重新定位到一個登陸頁面,截圖如下:
這個頁面是Spring Security自動幫我們生成的。我們可以使用之前配置的使用者名稱和密碼進行登入。自動生成這個頁面的程式碼位於類DefaultLoginPageGeneratingFilter的generateLoginPageHtml方法中。
免費學習影片歡迎關注雲圖智聯:https://e。yuntuzhilian。com/