【Spring Security】1.快速入門

xd會飛的貓發表於2020-08-10

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 實現流程

  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,密碼為控制檯列印的隨機碼。

  2. 可以在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 實現流程

  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();
        }
    }
  1. 自定義認證成功/失敗的處理邏輯

    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,否則鏈式呼叫的上下文會自動進入對應的標籤域。

相關文章