SpringSecurity系列之自定義登陸驗證成功與失敗的結果處理

1、須要自定義登陸結果的場景

在我以前的文章中,作過登陸驗證流程的源碼解析。其中比較重要的就是html

  • 當咱們登陸成功的時候,是由AuthenticationSuccessHandler進行登陸結果處理,默認跳轉到defaultSuccessUrl配置的路徑對應的資源頁面(通常是首頁index.html)。
  • 當咱們登陸失敗的時候,是由AuthenticationfailureHandler進行登陸結果處理,默認跳轉到failureUrl配置的路徑對應的資源頁面(通常是登陸頁login.html)。

可是在web應用開發過程當中需求是變幻無窮的,有時須要咱們針對登陸結果作個性化處理,好比:web

  • 咱們但願不一樣的人登錄以後,看到不一樣的首頁
  • 咱們應用是先後端分離的,驗證響應結果是JSON格式數據,而不是頁面跳轉

以上的這些狀況,使用Spring Security做爲安全框架的時候,都須要咱們使用本節學到的知識進行自定義的登陸驗證結果處理。spring

2、自定義登錄成功的結果處理

爲了知足上面的需求,咱們該如何去作呢?下面一小節咱們來講明一下。AuthenticationSuccessHandler接口是Security提供的認證成功處理器接口,咱們只須要去實現它便可。可是一般來講,咱們不會直接去實現AuthenticationSuccessHandler接口,而是繼承SavedRequestAwareAuthenticationSuccessHandler 類,這個類會記住用戶上一次請求的資源路徑,好比:用戶請求books.html,沒有登錄因此被攔截到了登陸頁,當你萬成登錄以後會自動跳轉到books.html,而不是主頁面。json

@Component
public class MyAuthenticationSuccessHandler 
                        extends SavedRequestAwareAuthenticationSuccessHandler {

    //在application配置文件中配置登錄的類型是JSON數據響應仍是作頁面響應
    @Value("${spring.security.logintype}")
    private String loginType;

    private  static ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, 
                                        HttpServletResponse response, 
                                        Authentication authentication) 
                                        throws ServletException, IOException {

        if (loginType.equalsIgnoreCase("JSON")) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(objectMapper.writeValueAsString(AjaxResponse.success()));
        } else {
            // 會幫咱們跳轉到上一次請求的頁面上
            super.onAuthenticationSuccess(request, response, authentication);
        }
    }
}
  • 在上面的自定義登錄成功處理中,既適應JSON先後端分離的應用登陸結果處理,也適用於模板頁面跳轉應用的登陸結果處理
  • ObjectMapper 是Spring Boot默認集成的JSON數據處理類庫Jackson中的類。
  • AjaxResponse是一個自定義的通用的JSON數據接口響應類。

3、自定義登陸失敗的結果處理

這裏咱們一樣沒有直接實現AuthenticationFailureHandler接口,而是繼承SimpleUrlAuthenticationFailureHandler 類。該類中默認實現了登陸驗證失敗的跳轉邏輯,即登錄失敗以後回到登陸頁面。咱們能夠利用這一點簡化咱們的代碼。後端

@Component
public class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {

    //在application配置文件中配置登錄的類型是JSON數據響應仍是作頁面響應
    @Value("${spring.security.logintype}")
    private String loginType;

    private  static ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void onAuthenticationFailure(HttpServletRequest request,
                                        HttpServletResponse response, 
                                        AuthenticationException exception) 
                                        throws IOException, ServletException {

        if (loginType.equalsIgnoreCase("JSON")) {
            response.setContentType("application/json;charset=UTF-8");
            response.getWriter().write(
                    objectMapper.writeValueAsString(
                            AjaxResponse.error(
                                    new CustomException(
                                        CustomExceptionType.USER_INPUT_ERROR,
                                        "用戶名或密碼存在錯誤,請檢查後再次登陸"))));
        } else {
            response.setContentType("text/html;charset=UTF-8");
            super.onAuthenticationFailure(request, response, exception);
        }

    }
}
  • 在上面的自定義登錄失敗處理中,既適應JSON先後端分離的應用登陸失敗結果處理,也適用於模板頁面跳轉應用的登陸失敗結果處理
  • 登錄失敗以後,將默認跳轉到默認的failureUrl,即登陸界面。

4、配置SecurityConfig

@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    private MyAuthenticationSuccessHandler myAuthenticationSuccessHandler;

    @Resource
    private MyAuthenticationFailureHandler myAuthenticationFailureHandler;

   @Override
   protected void configure(HttpSecurity http) throws Exception {
       http.csrf().disable() //禁用跨站csrf攻擊防護,後面的章節會專門講解
           .formLogin()
           .successHandler(myAuthenticationSuccessHandler)
           .failureHandler(myAuthenticationFailureHandler)
           .defaultSuccessUrl("/index")//登陸認證成功後默認轉跳的路徑
           .failureUrl("/login.html") //登陸認證是被跳轉頁面
}
  • 將自定義的AuthenticationSuccessHandler和AuthenticationFailureHandler注入到Spring Security配置類中
  • 使用fromlogin模式,配置successHandler和failureHandler。
  • 而且配置defaultSuccessUrl和failureUrl安全

    期待您的關注

  • 博主最近新寫了一本書:《手摸手教您學習SpringBoot系列-16章97節》
  • 本文轉載註明出處(必須帶鏈接,不能只轉文字):字母哥博客springboot

相關文章
相關標籤/搜索