解析SpringSecurity自定義登錄驗(yàn)證成功與失敗的結(jié)果處理問題
一、需要自定義登錄結(jié)果的場景
在我之前的文章中,做過登錄驗(yàn)證流程的源碼解析。其中比較重要的就是
- 當(dāng)我們登錄成功的時候,是由AuthenticationSuccessHandler進(jìn)行登錄結(jié)果處理,默認(rèn)跳轉(zhuǎn)到defaultSuccessUrl配置的路徑對應(yīng)的資源頁面(一般是首頁index.html)。
- 當(dāng)我們登錄失敗的時候,是由AuthenticationfailureHandler進(jìn)行登錄結(jié)果處理,默認(rèn)跳轉(zhuǎn)到failureUrl配置的路徑對應(yīng)的資源頁面(一般是登錄頁login.html)。
但是在web應(yīng)用開發(fā)過程中需求是千變?nèi)f化的,有時需要我們針對登錄結(jié)果做個性化處理,比如:
- 我們希望不同的人登陸之后,看到不同的首頁
- 我們應(yīng)用是前后端分離的,驗(yàn)證響應(yīng)結(jié)果是JSON格式數(shù)據(jù),而不是頁面跳轉(zhuǎn)
以上的這些情況,使用Spring Security作為安全框架的時候,都需要我們使用本節(jié)學(xué)到的知識進(jìn)行自定義的登錄驗(yàn)證結(jié)果處理。
二、自定義登陸成功的結(jié)果處理
為了滿足上面的需求,我們該如何去做呢?下面一小節(jié)我們來說明一下。AuthenticationSuccessHandler接口是Security提供的認(rèn)證成功處理器接口,我們只需要去實(shí)現(xiàn)它即可。但是通常來說,我們不會直接去實(shí)現(xiàn)AuthenticationSuccessHandler接口,而是繼承SavedRequestAwareAuthenticationSuccessHandler 類,這個類會記住用戶上一次請求的資源路徑,比如:用戶請求books.html,沒有登陸所以被攔截到了登錄頁,當(dāng)你萬成登陸之后會自動跳轉(zhuǎn)到books.html,而不是主頁面。
@Component public class MyAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler { //在application配置文件中配置登陸的類型是JSON數(shù)據(jù)響應(yīng)還是做頁面響應(yīng) @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 { // 會幫我們跳轉(zhuǎn)到上一次請求的頁面上 super.onAuthenticationSuccess(request, response, authentication); } } }
- 在上面的自定義登陸成功處理中,既適應(yīng)JSON前后端分離的應(yīng)用登錄結(jié)果處理,也適用于模板頁面跳轉(zhuǎn)應(yīng)用的登錄結(jié)果處理
- ObjectMapper 是Spring Boot默認(rèn)集成的JSON數(shù)據(jù)處理類庫Jackson中的類。
- AjaxResponse是一個自定義的通用的JSON數(shù)據(jù)接口響應(yīng)類。
三、自定義登錄失敗的結(jié)果處理
這里我們同樣沒有直接實(shí)現(xiàn)AuthenticationFailureHandler接口,而是繼承SimpleUrlAuthenticationFailureHandler 類。該類中默認(rèn)實(shí)現(xiàn)了登錄驗(yàn)證失敗的跳轉(zhuǎn)邏輯,即登陸失敗之后回到登錄頁面。我們可以利用這一點(diǎn)簡化我們的代碼。
@Component public class MyAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler { //在application配置文件中配置登陸的類型是JSON數(shù)據(jù)響應(yīng)還是做頁面響應(yīng) @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); } } }
- 在上面的自定義登陸失敗處理中,既適應(yīng)JSON前后端分離的應(yīng)用登錄失敗結(jié)果處理,也適用于模板頁面跳轉(zhuǎn)應(yīng)用的登錄失敗結(jié)果處理
- 登陸失敗之后,將默認(rèn)跳轉(zhuǎn)到默認(rèn)的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攻擊防御,后面的章節(jié)會專門講解 .formLogin() .successHandler(myAuthenticationSuccessHandler) .failureHandler(myAuthenticationFailureHandler) .defaultSuccessUrl("/index")//登錄認(rèn)證成功后默認(rèn)轉(zhuǎn)跳的路徑 .failureUrl("/login.html") //登錄認(rèn)證是被跳轉(zhuǎn)頁面 }
- 將自定義的AuthenticationSuccessHandler和AuthenticationFailureHandler注入到Spring Security配置類中
- 使用fromlogin模式,配置successHandler和failureHandler。
- 并且配置defaultSuccessUrl和failureUrl
總結(jié)
以上所述是小編給大家介紹的SpringSecurity自定義登錄驗(yàn)證成功與失敗的結(jié)果處理,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
如果你覺得本文對你有幫助,歡迎轉(zhuǎn)載,煩請注明出處,謝謝!
- SpringBoot+SpringSecurity處理Ajax登錄請求問題(推薦)
- SpringSecurity動態(tài)加載用戶角色權(quán)限實(shí)現(xiàn)登錄及鑒權(quán)功能
- 解決SpringSecurity 一直登錄失敗的問題
- SpringSecurity多表多端賬戶登錄的實(shí)現(xiàn)
- SpringBoot如何整合Springsecurity實(shí)現(xiàn)數(shù)據(jù)庫登錄及權(quán)限控制
- SpringSecurity6.x多種登錄方式配置小結(jié)
- SpringSecurity表單配置之登錄成功及頁面跳轉(zhuǎn)原理解析
- SpringSecurity集成第三方登錄過程詳解(最新推薦)
- Spring?Security重寫AuthenticationManager實(shí)現(xiàn)賬號密碼登錄或者手機(jī)號碼登錄
相關(guān)文章
redis redisson 限流器的實(shí)例(RRateLimiter)
這篇文章主要介紹了redis redisson 限流器的實(shí)例(RRateLimiter),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07詳解SpringBoot的三種緩存技術(shù)(Spring Cache、Layering Cache 框架、Alibaba J
這篇文章主要介紹了SpringBoot的三種緩存技術(shù),幫助大家更好的理解和學(xué)習(xí)springboot框架,感興趣的朋友可以了解下2020-10-10Spring boot通過HttpSessionListener監(jiān)聽器統(tǒng)計在線人數(shù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了Spring boot通過HttpSessionListener監(jiān)聽器統(tǒng)計在線人數(shù)的實(shí)現(xiàn)代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2018-02-02mybatis實(shí)現(xiàn)mapper代理模式的方式
本文向大家講解mybatis的mapper代理模式,以根據(jù)ide值查詢單條數(shù)據(jù)為例編寫xml文件,通過mapper代理的方式進(jìn)行講解增刪改查,分步驟給大家講解的很詳細(xì),對mybatis mapper代理模式相關(guān)知識感興趣的朋友一起看看吧2021-06-06通過FeignClient調(diào)用微服務(wù)提供的分頁對象IPage報錯的解決
這篇文章主要介紹了通過FeignClient調(diào)用微服務(wù)提供的分頁對象IPage報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03SpringBoot?2.x整合Log4j2日志的詳細(xì)步驟
log4j2優(yōu)越的性能其原因在于log4j2使用了LMAX,一個無鎖的線程間通信庫代替了,logback和log4j之前的隊列,并發(fā)性能大大提升,下面這篇文章主要給大家介紹了關(guān)于SpringBoot?2.x整合Log4j2日志的相關(guān)資料,需要的朋友可以參考下2022-10-10