一、需要自定義登錄結果的場景
在我之前的文章中,做過登錄驗證流程的源碼解析。其中比較重要的就是
- 當我們登錄成功的時候,是由AuthenticationSuccessHandler進行登錄結果處理,默認跳轉到defaultSuccessUrl配置的路徑對應的資源頁面(一般是首頁index.html)。
- 當我們登錄失敗的時候,是由AuthenticationfailureHandler進行登錄結果處理,默認跳轉到failureUrl配置的路徑對應的資源頁面(一般是登錄頁login.html)。
但是在web應用開發過程中需求是千變萬化的,有時需要我們針對登錄結果做個性化處理,比如:
- 我們希望不同的人登陸之後,看到不同的首頁
- 我們應用是前後端分離的,驗證響應結果是JSON格式數據,而不是頁面跳轉
以上的這些情況,使用Spring Security作為安全框架的時候,都需要我們使用本節學到的知識進行自定義的登錄驗證結果處理。
二、自定義登陸成功的結果處理
為了滿足上面的需求,我們該如何去做呢?下面一小節我們來說明一下。AuthenticationSuccessHandler接口是Security提供的認證成功處理器接口,我們只需要去實現它即可。但是通常來說,我們不會直接去實現AuthenticationSuccessHandler接口,而是繼承SavedRequestAwareAuthenticationSuccessHandler 類,這個類會記住用戶上一次請求的資源路徑,比如:用戶請求books.html,沒有登陸所以被攔截到了登錄頁,當你萬成登陸之後會自動跳轉到books.html,而不是主頁面。
@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數據接口響應類。
三、自定義登錄失敗的結果處理
這裏我們同樣沒有直接實現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,即登錄界面。
四、配置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
期待您的關注
- 博主最近新寫了一本書:
-
本文轉載註明出處(必須帶連接,不能只轉文字):。
本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理
【其他文章推薦】
※網頁設計公司推薦更多不同的設計風格,搶佔消費者視覺第一線
※廣告預算用在刀口上,網站設計公司幫您達到更多曝光效益
※自行創業 缺乏曝光? 下一步"網站設計"幫您第一時間規劃公司的門面形象
※台灣寄大陸海運貨物規則及重量限制?
※大陸寄台灣海運費用試算一覽表