Spring Security(三)--核心配置解讀
上一篇文章《Spring Security(二)--Guides》,透過Spring Security的配置項瞭解了Spring Security是如何保護我們的應用的,本篇文章對上一次的配置做一個分析。
目錄
核心配置解讀
3.1 功能介紹
3.2 EnableWebSecurity
WebSecurityConfiguration
AuthenticationConfiguration
3.3 WebSecurityConfigurerAdapter
HttpSecurity常用配置
WebSecurityBuilder
AuthenticationManagerBuilder
3 核心配置解讀
3.1 功能介紹
這是Spring Security入門指南中的配置項:
@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/", "/home").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll(); } @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("admin").password("admin").roles("USER"); }}
當配置了上述的javaconfig之後,我們的應用便具備瞭如下的功能:
除了“/”,"/home"(首頁),"/login"(登入),"/logout"(登出),之外,其他路徑都需要認證。
指定“/login”該路徑為登入頁面,當未認證的使用者嘗試訪問任何受保護的資源時,都會跳轉到“/login”。
預設指定“/logout”為登出頁面
配置一個記憶體中的使用者認證器,使用admin/admin作為使用者名稱和密碼,具有USER角色
防止CSRF攻擊
Session Fixation protection(可以參考我之前講解Spring Session的文章,防止別人篡改sessionId)
Security Header(新增一系列和Header相關的控制)
HTTP Strict Transport Security for secure requests
整合X-Content-Type-Options
快取控制
整合X-XSS-Protection
X-Frame-Options integration to help prevent Clickjacking(iframe被預設禁止使用)
為Servlet API整合了如下的幾個方法
HttpServletRequest#getRemoteUser()
HttpServletRequest.html#getUserPrincipal()
HttpServletRequest.html#isUserInRole(java.lang.String)
HttpServletRequest.html#login(java.lang.String, java.lang.String)
HttpServletRequest.html#logout()
3.2 @EnableWebSecurity
我們自己定義的配置類WebSecurityConfig加上了@EnableWebSecurity註解,同時繼承了WebSecurityConfigurerAdapter。你可能會在想誰的作用大一點,毫無疑問@EnableWebSecurity起到決定性的配置作用,它其實是個組合註解。
@Import({ WebSecurityConfiguration.class, // SpringWebMvcImportSelector.class }) // @EnableGlobalAuthentication // @Configurationpublic @interface EnableWebSecurity { boolean debug() default false;}
@Import是springboot提供的用於引入外部的配置的註解,可以理解為:@EnableWebSecurity註解啟用了@Import註解中包含的配置類。
@Import(AuthenticationConfiguration.class)@Configurationpublic @interface EnableGlobalAuthentication {}
注意點同樣在@Import之中,它實際上啟用了AuthenticationConfiguration這樣的一個配置類,用來配置認證相關的核心類。
也就是說:@EnableWebSecurity完成的工作便是載入了WebSecurityConfiguration,AuthenticationConfiguration這兩個核心配置類,也就此將spring security的職責劃分為了配置安全資訊,配置認證資訊兩部分。
WebSecurityConfiguration
在這個配置類中,有一個非常重要的Bean被註冊了。
@Configurationpublic class WebSecurityConfiguration { //DEFAULT_FILTER_NAME = "springSecurityFilterChain" @Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME) public Filter springSecurityFilterChain() throws Exception { ... } }
在未使用springboot之前,大多數人都應該對“springSecurityFilterChain”這個名詞不會陌生,他是spring security的核心過濾器,是整個認證的入口。在曾經的XML配置中,想要啟用spring security,需要在web.xml中進行如下配置:
springSecurityFilterChain org.springframework.web.filter.DelegatingFilterProxy springSecurityFilterChain /*
而在springboot整合之後,這樣的XML被java配置取代。WebSecurityConfiguration中完成了宣告springSecurityFilterChain的作用,並且最終交給DelegatingFilterProxy這個代理類,負責攔截請求(注意DelegatingFilterProxy這個類不是spring security包中的,而是存在於web包中,spring使用了代理模式來實現安全過濾的解耦)。
AuthenticationConfiguration
@Configuration@Import(ObjectPostProcessorConfiguration.class)public class AuthenticationConfiguration { @Bean public AuthenticationManagerBuilder authenticationManagerBuilder( ObjectPostProcessor objectPostProcessor) { return new AuthenticationManagerBuilder(objectPostProcessor); } public AuthenticationManager getAuthenticationManager() throws Exception { ... }}
AuthenticationConfiguration的主要任務,便是負責生成全域性的身份認證管理者AuthenticationManager。還記得在《Spring Security(一)--Architecture Overview》中,介紹了Spring Security的認證體系,AuthenticationManager便是最核心的身份認證管理器。
3.3 WebSecurityConfigurerAdapter
介面卡模式在spring中被廣泛的使用,在配置中使用Adapter的好處便是,我們可以選擇性的配置想要修改的那一部分配置,而不用覆蓋其他不相關的配置。WebSecurityConfigurerAdapter中我們可以選擇自己想要修改的內容,來進行重寫,而其提供了三個configure過載方法,是我們主要關心的:
由引數就可以知道,分別是對AuthenticationManagerBuilder,WebSecurity,HttpSecurity進行個性化的配置。
HttpSecurity常用配置
@Configuration@EnableWebSecuritypublic class CustomWebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/resources/**", "/signup", "/about").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')") .anyRequest().authenticated() .and() .formLogin() .usernameParameter("username") .passwordParameter("password") .failureForwardUrl("/login?error") .loginPage("/login") .permitAll() .and() .logout() .logoutUrl("/logout") .logoutSuccessUrl("/index") .permitAll() .and() .httpBasic() .disable(); }}
上述是一個使用Java Configuration配置HttpSecurity的典型配置,其中http作為根開始配置,每一個and()對應了一個模組的配置(等同於xml配置中的結束標籤),並且and()返回了HttpSecurity本身,於是可以連續進行配置。他們配置的含義也非常容易透過變數本身來推測,
authorizeRequests()配置路徑攔截,表明路徑訪問所對應的許可權,角色,認證資訊。
formLogin()對應表單認證相關的配置
logout()對應了登出相關的配置
httpBasic()可以配置basic登入
etc
他們分別代表了http請求相關的安全配置,這些配置項無一例外的返回了Configurer類,而所有的http相關配置可以透過檢視HttpSecurity的主要方法得知:
需要對http協議有一定的瞭解才能完全掌握所有的配置,不過,springboot和spring security的自動配置已經足夠使用了。其中每一項Configurer(e.g.FormLoginConfigurer,CsrfConfigurer)都是HttpConfigurer的細化配置項。
WebSecurityBuilder
@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override public void configure(WebSecurity web) throws Exception { web .ignoring() .antMatchers("/resources/**"); }}
以筆者的經驗,這個配置中並不會出現太多的配置資訊。
AuthenticationManagerBuilder
@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("admin").password("admin").roles("USER"); }}
想要在WebSecurityConfigurerAdapter中進行認證相關的配置,可以使用configure(AuthenticationManagerBuilder auth)暴露一個AuthenticationManager的建造器:AuthenticationManagerBuilder 。如上所示,我們便完成了記憶體中使用者的配置。
細心的朋友會發現,在前面的文章中我們配置記憶體中的使用者時,似乎不是這麼配置的,而是:
@Configuration@EnableWebSecuritypublic class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { auth .inMemoryAuthentication() .withUser("admin").password("admin").roles("USER"); }}
如果你的應用只有唯一一個WebSecurityConfigurerAdapter,那麼他們之間的差距可以被忽略,從方法名可以看出兩者的區別:使用@Autowired注入的AuthenticationManagerBuilder是全域性的身份認證器,作用域可以跨越多個WebSecurityConfigurerAdapter,以及影響到基於Method的安全控制;而 protectedconfigure()
的方式則類似於一個匿名內部類,它的作用域侷限於一個WebSecurityConfigurerAdapter內部。關於這一點的區別,可以參考我曾經提出的issue:spring-security#issues4571。官方文件中,也給出了配置多個WebSecurityConfigurerAdapter的場景以及demo,將在該系列的後續文章中解讀。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31556476/viewspace-2215733/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 淺析Spring Security 核心元件Spring元件
- Spring Boot Security配置教程Spring Boot
- Spring Security詳解Spring
- Spring Security 核心過濾器鏈分析Spring過濾器
- Spring Boot Security 詳解Spring Boot
- Spring Security 快速瞭解Spring
- 深入Spring Security-獲取認證機制核心原理講解Spring
- Spring security(三)---認證過程Spring
- Spring Boot核心配置Spring Boot
- 讀懂這些spring boot的核心註解,快速配置完成專案搭建Spring Boot
- Spring Security配置好了不起作用Spring
- Spring Security (三):與Vue.js整合SpringVue.js
- 深入Spring Security魔幻山谷-獲取認證機制核心原理講解(新版)Spring
- 【詳解】Spring Security 之 SecurityContextSpringContext
- spring security 問題解決方案Spring
- Spring Boot 讀取配置內容的三種方式Spring Boot
- [譯] 學習 Spring Security(三):註冊流程Spring
- Spring SecuritySpring
- Spring Security系列之核心過濾器原始碼分析(四)Spring過濾器原始碼
- Spring Security原始碼分析八:Spring Security 退出Spring原始碼
- Spring Boot —— Spring SecuritySpring Boot
- Spring Security原始碼分析九:Spring Security Session管理Spring原始碼Session
- Spring-讀取配置Spring
- Spring Security 實戰乾貨:圖解Spring Security中的Servlet過濾器體系Spring圖解Servlet過濾器
- Laravel核心解讀 — RequestLaravel
- Spring Security(二)--WebSecurityConfigurer配置以及filter順序SpringWebFilter
- Spring Security配置個過濾器也這麼卷Spring過濾器
- Spring Boot核心原理-自動配置Spring Boot
- Spring Security 上Spring
- 初探Spring SecuritySpring
- Spring Security(二)Spring
- spring security(一)Spring
- Spring Security(6)Spring
- Spring Security(7)Spring
- Spring Security(8)Spring
- Spring Security + JWTSpringJWT
- Spring Boot SecuritySpring Boot
- Spring Security研究Spring