SpringSecurity6.x多種登錄方式配置小結(jié)
SpringSecurity6.x變了很多寫法。
在編寫多種登錄方式的時(shí)候,網(wǎng)上大多是5.x的,很多類都沒了。
以下是SpringSecurity6.x多種登錄方式的寫法。
1. 編寫第一種登錄-賬號(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. 編寫第二種登錄方式-手機(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. 編寫驗(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;
}
//獲取過濾器封裝的token信息
PhoneCodeLoginAuthticationToken authenticationToken = (PhoneCodeLoginAuthticationToken) authentication;
String username = (String)authenticationToken.getPrincipal();
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
// 不通過
if (userDetails == null) {
throw new BadCredentialsException("用戶不存在");
}
// 根用戶擁有全部的權(quán)限
PhoneCodeLoginAuthticationToken authenticationResult = new PhoneCodeLoginAuthticationToken(userDetails, null);
return authenticationResult;
}
@Override
public boolean supports(Class<?> authentication) {
return PhoneCodeLoginAuthticationToken.class.isAssignableFrom(authentication);
}
}
4. 配置SecurityConfiguration,把上邊的兩個(gè) 登錄過濾器加到過濾器鏈中。
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è)置用戶信息處理器
daoAuthenticationProvider.setUserDetailsService(userDetailService);
//設(shè)置密碼處理器
daoAuthenticationProvider.setPasswordEncoder(passwordEncoder);
AuthenticationManagerBuilder authenticationManagerBuilder =
http.getSharedObject(AuthenticationManagerBuilder.class);
authenticationManagerBuilder.authenticationProvider(phoneCodeLoginProvider);//自定義的
authenticationManagerBuilder.authenticationProvider(daoAuthenticationProvider);//原來默認(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)求問題(推薦)
- 解析SpringSecurity自定義登錄驗(yàn)證成功與失敗的結(jié)果處理問題
- SpringSecurity動(dòng)態(tài)加載用戶角色權(quán)限實(shí)現(xiàn)登錄及鑒權(quán)功能
- 解決SpringSecurity 一直登錄失敗的問題
- SpringSecurity多表多端賬戶登錄的實(shí)現(xiàn)
- SpringBoot如何整合Springsecurity實(shí)現(xiàn)數(shù)據(jù)庫登錄及權(quán)限控制
- SpringSecurity表單配置之登錄成功及頁面跳轉(zhuǎn)原理解析
- SpringSecurity集成第三方登錄過程詳解(最新推薦)
- Spring?Security重寫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ù)庫
這篇文章主要介紹了在SpringBoot項(xiàng)目中使用Oracle11g數(shù)據(jù)庫的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
使用IDEA創(chuàng)建Java Web項(xiàng)目并部署訪問的圖文教程
本文通過圖文并茂的形式給大家介紹了使用IDEA創(chuàng)建Java Web項(xiàng)目并部署訪問的教程,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08
SpringBoot項(xiàng)目的配置文件中設(shè)置server.port不生效問題
這篇文章主要介紹了SpringBoot項(xiàng)目的配置文件中設(shè)置server.port不生效問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-11-11

