SpringSecurity6.x多種登錄方式配置小結(jié)
SpringSecurity6.x變了很多寫(xiě)法。
在編寫(xiě)多種登錄方式的時(shí)候,網(wǎng)上大多是5.x的,很多類(lèi)都沒(méi)了。
以下是SpringSecurity6.x多種登錄方式的寫(xiě)法。
1. 編寫(xiě)第一種登錄-賬號(hào)密碼json登錄方式
package com.hw.mo.security.filter; import com.fasterxml.jackson.databind.ObjectMapper; import com.hw.mo.captcha.config.CaptchaConfig; import com.hw.mo.security.entity.LoginUser; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import java.io.IOException; /** * @author : guanzheng * @date : 2023/6/26 15:17 */ public class JsonLoginFilter extends UsernamePasswordAuthenticationFilter { public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { String contentType = request.getContentType(); if (MediaType.APPLICATION_JSON_VALUE.equalsIgnoreCase(contentType) || MediaType.APPLICATION_JSON_UTF8_VALUE.equalsIgnoreCase(contentType)) { if (!request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } String username = null; String password = null; try { LoginUser user = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class); username = user.getUsername(); username = (username != null) ? username.trim() : ""; password = user.getPassword(); password = (password != null) ? password : ""; } catch (IOException e) { throw new RuntimeException(e); } UsernamePasswordAuthenticationToken authRequest = UsernamePasswordAuthenticationToken.unauthenticated(username, password); setDetails(request, authRequest); return this.getAuthenticationManager().authenticate(authRequest); } return super.attemptAuthentication(request,response); } }
2. 編寫(xiě)第二種登錄方式-手機(jī)驗(yàn)證碼登錄
package com.hw.mo.security.filter; import com.fasterxml.jackson.databind.ObjectMapper; import com.hw.mo.security.domain.PhoneCodeLoginAuthticationToken; import com.hw.mo.security.entity.LoginUser; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import org.springframework.http.MediaType; import org.springframework.security.authentication.AuthenticationServiceException; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.util.matcher.AntPathRequestMatcher; import java.io.IOException; public class PhoneCodeLoginFilter extends AbstractAuthenticationProcessingFilter { public PhoneCodeLoginFilter() { super(new AntPathRequestMatcher("/loginPhoneCode","POST")); } @Override public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException { // 需要是 POST 請(qǐng)求 if (!request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } // 判斷請(qǐng)求格式是否 JSON if (request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) { LoginUser user = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class); // 獲得請(qǐng)求參數(shù) String username = user.getUsername(); String phoneCode = user.getPhoneCode(); String captchaUuid = user.getCaptchaUuid(); //TODO 檢查驗(yàn)證碼是否正確 if (CaptchaUtil.validate(captchaUuid,phoneCode).isOk()){ } /** * 使用請(qǐng)求參數(shù)傳遞的郵箱和驗(yàn)證碼,封裝為一個(gè)未認(rèn)證 EmailVerificationCodeAuthenticationToken 身份認(rèn)證對(duì)象, * 然后將該對(duì)象交給 AuthenticationManager 進(jìn)行認(rèn)證 */ PhoneCodeLoginAuthticationToken token = new PhoneCodeLoginAuthticationToken(username); setDetails(request, token); return this.getAuthenticationManager().authenticate(token); } return null; } public void setDetails(HttpServletRequest request , PhoneCodeLoginAuthticationToken token){ token.setDetails(this.authenticationDetailsSource.buildDetails(request)); } }
3. 編寫(xiě)驗(yàn)證碼登錄處理器
package com.hw.mo.security.provider; import com.hw.mo.security.domain.PhoneCodeLoginAuthticationToken; import org.springframework.security.authentication.AuthenticationProvider; import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.core.Authentication; import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.stereotype.Component; @Component public class PhoneCodeLoginProvider implements AuthenticationProvider { UserDetailsService userDetailsService; public PhoneCodeLoginProvider(UserDetailsService userDetailsService){ this.userDetailsService = userDetailsService; } @Override public Authentication authenticate(Authentication authentication) throws AuthenticationException { if (authentication.isAuthenticated()) { return authentication; } //獲取過(guò)濾器封裝的token信息 PhoneCodeLoginAuthticationToken authenticationToken = (PhoneCodeLoginAuthticationToken) authentication; String username = (String)authenticationToken.getPrincipal(); UserDetails userDetails = userDetailsService.loadUserByUsername(username); // 不通過(guò) if (userDetails == null) { throw new BadCredentialsException("用戶(hù)不存在"); } // 根用戶(hù)擁有全部的權(quán)限 PhoneCodeLoginAuthticationToken authenticationResult = new PhoneCodeLoginAuthticationToken(userDetails, null); return authenticationResult; } @Override public boolean supports(Class<?> authentication) { return PhoneCodeLoginAuthticationToken.class.isAssignableFrom(authentication); } }
4. 配置SecurityConfiguration,把上邊的兩個(gè) 登錄過(guò)濾器加到過(guò)濾器鏈中。
package com.hw.mo.security.config; import com.hw.mo.security.filter.JsonLoginFilter; import com.hw.mo.security.filter.JwtAuthenticationFilter; import com.hw.mo.security.filter.PhoneCodeLoginFilter; import com.hw.mo.security.handler.*; import com.hw.mo.security.provider.PhoneCodeLoginProvider; import com.hw.mo.security.service.impl.LoginUserDetailServiceImpl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; /** * @author : guanzheng * @date : 2023/6/25 9:03 */ @Configuration @EnableWebSecurity public class SecurityConfiguration { @Autowired LoginUserDetailServiceImpl userDetailService; @Autowired MoPasswordEncoder passwordEncoder; @Autowired PhoneCodeLoginProvider phoneCodeLoginProvider; @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authorize)-> authorize .requestMatchers("/rongyan/**","/login*","/captcha*","/register*").permitAll() .anyRequest().authenticated() ) .addFilterBefore(new JwtAuthenticationFilter(),UsernamePasswordAuthenticationFilter.class) .exceptionHandling(e-> { e.accessDeniedHandler(new MyAccessDeniedHandler()); e.authenticationEntryPoint(new AuthenticatedErrorHandler()); }) .csrf(csrf -> csrf.disable()) .cors(cors -> cors.disable()) ; return http.build(); } /** * 加載賬號(hào)密碼json登錄 */ @Bean JsonLoginFilter myJsonLoginFilter(HttpSecurity http) throws Exception { JsonLoginFilter myJsonLoginFilter = new JsonLoginFilter(); //自定義登錄url myJsonLoginFilter.setFilterProcessesUrl("/login"); myJsonLoginFilter.setAuthenticationSuccessHandler(new LoginSuccessHandler()); myJsonLoginFilter.setAuthenticationFailureHandler(new LoginFailureHandler()); myJsonLoginFilter.setAuthenticationManager(authenticationManager(http)); return myJsonLoginFilter; } /** * 加載手機(jī)驗(yàn)證碼登錄 */ @Bean PhoneCodeLoginFilter phoneCodeLoginFilter(HttpSecurity http) throws Exception { PhoneCodeLoginFilter phoneCodeLoginFilter = new PhoneCodeLoginFilter(); //自定義登錄url phoneCodeLoginFilter.setFilterProcessesUrl("/loginPhoneCode"); phoneCodeLoginFilter.setAuthenticationSuccessHandler(new LoginSuccessHandler()); phoneCodeLoginFilter.setAuthenticationFailureHandler(new LoginFailureHandler()); phoneCodeLoginFilter.setAuthenticationManager(authenticationManager(http)); return phoneCodeLoginFilter; } @Bean AuthenticationManager authenticationManager(HttpSecurity http) throws Exception { DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider(); //設(shè)置用戶(hù)信息處理器 daoAuthenticationProvider.setUserDetailsService(userDetailService); //設(shè)置密碼處理器 daoAuthenticationProvider.setPasswordEncoder(passwordEncoder); AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class); authenticationManagerBuilder.authenticationProvider(phoneCodeLoginProvider);//自定義的 authenticationManagerBuilder.authenticationProvider(daoAuthenticationProvider);//原來(lái)默認(rèn)的 return authenticationManagerBuilder.build(); } }
到此這篇關(guān)于SpringSecurity6.x多種登錄方式配置小結(jié)的文章就介紹到這了,更多相關(guān)SpringSecurity6.x 登錄內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot+SpringSecurity處理Ajax登錄請(qǐng)求問(wèn)題(推薦)
- 解析SpringSecurity自定義登錄驗(yàn)證成功與失敗的結(jié)果處理問(wèn)題
- SpringSecurity動(dòng)態(tài)加載用戶(hù)角色權(quán)限實(shí)現(xiàn)登錄及鑒權(quán)功能
- 解決SpringSecurity 一直登錄失敗的問(wèn)題
- SpringSecurity多表多端賬戶(hù)登錄的實(shí)現(xiàn)
- SpringBoot如何整合Springsecurity實(shí)現(xiàn)數(shù)據(jù)庫(kù)登錄及權(quán)限控制
- SpringSecurity表單配置之登錄成功及頁(yè)面跳轉(zhuǎn)原理解析
- SpringSecurity集成第三方登錄過(guò)程詳解(最新推薦)
- Spring?Security重寫(xiě)AuthenticationManager實(shí)現(xiàn)賬號(hào)密碼登錄或者手機(jī)號(hào)碼登錄
相關(guān)文章
Java程序設(shè)計(jì)之12個(gè)經(jīng)典樣例
這篇文章主要給大家分享關(guān)于Java程序設(shè)計(jì)11個(gè)經(jīng)典樣例,主要以舉例的形式詳細(xì)的講解了Java程序設(shè)計(jì)的各種方法,需要的朋友可以參考一下文章具體的內(nèi)容2021-10-10如何在SpringBoot項(xiàng)目中使用Oracle11g數(shù)據(jù)庫(kù)
這篇文章主要介紹了在SpringBoot項(xiàng)目中使用Oracle11g數(shù)據(jù)庫(kù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06通過(guò)IDEA快速定位和排除依賴(lài)沖突問(wèn)題
這篇文章主要介紹了通過(guò)IDEA快速定位和排除依賴(lài)沖突問(wèn)題,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-06-06使用IDEA創(chuàng)建Java Web項(xiàng)目并部署訪問(wèn)的圖文教程
本文通過(guò)圖文并茂的形式給大家介紹了使用IDEA創(chuàng)建Java Web項(xiàng)目并部署訪問(wèn)的教程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08SpringBoot如何使用過(guò)濾器進(jìn)行XSS防御
想對(duì)全局的請(qǐng)求都進(jìn)行XSS防御可以使用servlet中的過(guò)濾器或者spring mvc中的攔截器,下面我們就來(lái)看看如何使用servlet中的過(guò)濾器進(jìn)行XSS防御吧2024-11-11SpringBoot項(xiàng)目的配置文件中設(shè)置server.port不生效問(wèn)題
這篇文章主要介紹了SpringBoot項(xiàng)目的配置文件中設(shè)置server.port不生效問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11