SpringSecurity6.x多种登录方式配置小结
更新时间:2023年12月29日 10:29:15 作者:泉城打码师
SpringSecurity6.x变了很多写法,本文就来介绍一下SpringSecurity6.x多种登录方式配置小结,具有一定的参考价值,感兴趣的可以了解一下
SpringSecurity6.x变了很多写法。
在编写多种登录方式的时候,网上大多是5.x的,很多类都没了。
以下是SpringSecurity6.x多种登录方式的写法。
1. 编写第一种登录-账号密码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. 编写第二种登录方式-手机验证码登录
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 请求 if (!request.getMethod().equals("POST")) { throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod()); } // 判断请求格式是否 JSON if (request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) { LoginUser user = new ObjectMapper().readValue(request.getInputStream(), LoginUser.class); // 获得请求参数 String username = user.getUsername(); String phoneCode = user.getPhoneCode(); String captchaUuid = user.getCaptchaUuid(); //TODO 检查验证码是否正确 if (CaptchaUtil.validate(captchaUuid,phoneCode).isOk()){ } /** * 使用请求参数传递的邮箱和验证码,封装为一个未认证 EmailVerificationCodeAuthenticationToken 身份认证对象, * 然后将该对象交给 AuthenticationManager 进行认证 */ 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. 编写验证码登录处理器
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("用户不存在"); } // 根用户拥有全部的权限 PhoneCodeLoginAuthticationToken authenticationResult = new PhoneCodeLoginAuthticationToken(userDetails, null); return authenticationResult; } @Override public boolean supports(Class<?> authentication) { return PhoneCodeLoginAuthticationToken.class.isAssignableFrom(authentication); } }
4. 配置SecurityConfiguration,把上边的两个 登录过滤器加到过滤器链中。
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(); } /** * 加载账号密码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; } /** * 加载手机验证码登录 */ @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(); //设置用户信息处理器 daoAuthenticationProvider.setUserDetailsService(userDetailService); //设置密码处理器 daoAuthenticationProvider.setPasswordEncoder(passwordEncoder); AuthenticationManagerBuilder authenticationManagerBuilder = http.getSharedObject(AuthenticationManagerBuilder.class); authenticationManagerBuilder.authenticationProvider(phoneCodeLoginProvider);//自定义的 authenticationManagerBuilder.authenticationProvider(daoAuthenticationProvider);//原来默认的 return authenticationManagerBuilder.build(); } }
到此这篇关于SpringSecurity6.x多种登录方式配置小结的文章就介绍到这了,更多相关SpringSecurity6.x 登录内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
您可能感兴趣的文章:
- SpringSecurity多表多端账户登录的实现
- SpringSecurity集成第三方登录过程详解(最新推荐)
- springsecurity实现用户登录认证快速使用示例代码(前后端分离项目)
- SpringSecurity自动登录流程与实现详解
- SpringSecurity6自定义JSON登录的实现
- 如何使用JWT的SpringSecurity实现前后端分离
- SpringSecurity+Redis+Jwt实现用户认证授权
- SpringSecurity角色权限控制(SpringBoot+SpringSecurity+JWT)
- SpringBoot3.0+SpringSecurity6.0+JWT的实现
- springSecurity之如何添加自定义过滤器
- springSecurity自定义登录接口和JWT认证过滤器的流程
相关文章
Springboot+Redis实现API接口防刷限流的项目实践
本文主要介绍了Springboot+Redis实现API接口防刷限流的项目实践,通过限流可以让系统维持在一个相对稳定的状态,为更多的客户提供服务,具有一定的参考价值,感兴趣的可以了解一下2024-07-07new出来的对象中无法使用@autowired进行对象bean注入问题
这篇文章主要介绍了基于new出来的对象中无法使用@autowired进行对象bean注入问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-02-02
最新评论