【Spring Security】1.快速入門
- 2020 年 8 月 10 日
- 筆記
- spring security
1 導入Spring Security的相關依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2 Spring Security認證方式之Http基本認證
2.1 實現流程
-
Http基本認證是最簡單的認證方式,不需要任何配置,導入依賴啟動應用後就會彈出默認的httpBasic認證框。也相當於在實現了BrowserSecurityConfig類進行了如下配置:
@Configuration public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { //HttpBasic的alert框登錄 http.httpBasic() .and() .authorizeRequests()//對請求進行授權 .anyRequest()//任何請求 .authenticated(); } }
在Spring Security的默認配置中,使用用戶名user,密碼為控制台打印的隨機碼。
-
可以在resources配置文件中修改默認的用戶名和密碼,指定密碼後控制台不再生成動態的隨機碼。
- properties配置
-
security.user.name=user security.user.password=123456
- yml配置
-
spring: security: user: name: user password: 123456
2.2 Http基本認證原理
-
客戶端向服務端請求被保護的資源,服務端向客戶端請求用戶名和密碼,瀏覽器彈出登錄輸入框,HttpBasic模式要求傳輸的用戶名密碼使用Base64模式進行加密。客戶端向服務端發起login的請求。
-
客戶端發送的Http請求中會使用Authorization作為Header,即「Basic + 空格 + Base64密碼」。而Base64很容易被逆向解碼,所以HttpBstic的認證方式是不安全的。
服務器接收到請求後,到達BasicAuthenticationFilter過濾器,將提取Header值,並使用用於驗證用戶身份的相同算法Base64進行解碼。解碼結果與登錄驗證的用戶名密碼匹配,匹配成功則可以繼續過濾器後續的訪問。
2.3 小結
Http認證雖然配置簡單,但是安全性極差,靈活性不高,無法攜帶cookie,所以一般應用會用安全性和靈活性更強的表單認證方式,可以通過自定義登錄和驗證邏輯,提高安全性。
3 表單認證
3.1 實現流程
-
配置使用自定義的表單登錄
@Configuration public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // 表單登錄,而不是httpBasic http.formLogin() // 自定義登錄頁面 .loginPage("login.html") // 指定處理登錄請求的路徑 .loginProcessingUrl("/login") // 不限制登錄頁面的訪問 .permitAll() .and() .authorizeRequests()//對請求進行授權 .anyRequest()//任何請求 .authenticated() .and() .csrf() .disable(); } }
-
自定義認證成功/失敗的處理邏輯
Spring Security中默認的成功處理邏輯定義在AbstractAuthenticationTargetUrlRequestHandler類中,在發送登錄請求並認證成功後頁面會跳轉回到原來的訪問頁面,頁面跳轉不適用於前後端分離的系統中,因此可以自定義成功後的處理邏輯,登錄後返回JSON數據。
實現AuthenticationSuccessHandler和 AuthenticationFailureHandle類中的處理方法。
@Component("customAuthenticationSuccessHandler") public class CustomAuthenticationSuccessHandler implements AuthenticationSuccessHandler { @Autowired private ObjectMapper objectMapper; @Override public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException { httpServletResponse.setContentType("application/json;charset=UTF-8"); httpServletResponse.getWriter().write(objectMapper.writeValueAsString(authentication)); } }
@Component("customAuthenticationFailureHandler") public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { @Override public void onAuthenticationFailure(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, AuthenticationException e) throws IOException, ServletException { log.info("登錄失敗"); httpServletResponse.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR); httpServletResponse.setContentType("application/json;charset=UTF-8"); httpServletResponse.getWriter().write(e.getMessage()); } }
在WebSecurity配置文件中配置自定義的處理器
@Configuration public class BrowserSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // 表單登錄,而不是httpBasic http.formLogin() // 自定義登錄頁面 .loginPage("login.html") // 不限制登錄頁面的訪問 .permitAll() // 自定義認證後的處理器 .successHandler(customAuthenticationSuccessHandler) .failureHandler(customAuthenticationFailureHandler) .and() .authorizeRequests()//對請求進行授權 .anyRequest()//任何請求 .authenticated() .and() .csrf() .disable(); } }
3.2 關於HttpSecurity
在配置文件中使用HttpSecurity進行HTTP請求安全策略的配置,HttpSecurity被設計為鏈式調用,執行每個方法會返回一個預期的上下文,用於連續調用,其中:
-
authorizeRequests()相當於XML中的<intercept-url>標籤,它返回一個URL攔截註冊器,可以調用它提供的anyRequest()、antMatchers()、regexMatchers()等方法來匹配系統的URL,並為它指定安全策略。
-
formLogin()相當於XML中的<form-login>標籤,聲明了需要Spring Security提供的表單認證方式,返回對應的配置器,loginPage()用於指定自定義的登錄頁面。Spring Security會為該登錄頁註冊一個POST路由用於接收登錄請求。
-
httpBasic()相當於XML中的<http-basic>標籤
-
csrf()相當於XML中的<csrf>標籤,提供了跨站請求偽造防護功能,繼承WebSecurityConfigurerAdapter會默認開啟csrf()方法。
使用and()方法可以結束當前標籤,上下文會回到HttpSecurity,否則鏈式調用的上下文會自動進入對應的標籤域。