当前位置: 首页 > news >正文

spring boot security 自定义AuthenticationProvider

spring boot security 自定义AuthenticationProvider

基于 spring boot 3.x

场景实现 手机验证码登陆

实现

CaptureCodeAuthenticationFilter

public class CaptureCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {private static final String DEFAULT_LOGIN_URL = "/capture/login";private static final String DEFAULT_PHONE_NAME = "phone";private static final String DEFAULT_CODE_NAME = "code";private String codeParamName = DEFAULT_CODE_NAME;private String phoneParamName = DEFAULT_PHONE_NAME;public CaptureCodeAuthenticationFilter(AuthenticationManager authenticationManager) {super(DEFAULT_LOGIN_URL, authenticationManager);}public CaptureCodeAuthenticationFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager) {super(defaultFilterProcessesUrl, authenticationManager);}@Overridepublic Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {if (!request.getMethod().equals("POST")) {throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());}String phone = obtainPhone(request);phone = (phone != null) ? phone.trim() : "";String code = obtainCaptureCode(request);code = (code != null) ? code : "";CaptureCodeAuthenticationToken token = new CaptureCodeAuthenticationToken(phone, code);return this.getAuthenticationManager().authenticate(token);}protected String obtainCaptureCode(HttpServletRequest request) {return request.getParameter(this.codeParamName);}protected String obtainPhone(HttpServletRequest request) {return request.getParameter(this.phoneParamName);}
}

CaptureCodeAuthenticationToken

public class CaptureCodeAuthenticationToken extends UsernamePasswordAuthenticationToken {public CaptureCodeAuthenticationToken(Object principal, Object credentials) {super(principal, credentials);}
}

CaptureCodeAuthenticationProvider

public class CaptureCodeAuthenticationProvider extends AbstractUserDetailsAuthenticationProvider {@Overridepublic boolean supports(Class<?> authentication) {return (CaptureCodeAuthenticationToken.class.isAssignableFrom(authentication));}@Overrideprotected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {if (authentication.getPrincipal()==null){throw new BadCredentialsException("Bad credentials "+ authentication.getPrincipal().toString());}if (authentication.getCredentials()==null){throw new BadCredentialsException("Bad credentials "+ authentication.getPrincipal().toString());}}@Overrideprotected UserDetails retrieveUser(String username, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {CaptureCodeAuthenticationToken token = (CaptureCodeAuthenticationToken) authentication;if (!token.getPrincipal().equals("tom")){throw new UsernameNotFoundException("username not fund!");}UserDetails user = User.withUsername("tom").password("tom").build();return user;}}

配置 DefaultSecurityConfig

@Configuration
@EnableWebSecurity
public class DefaultSecurityConfig {@Autowiredprivate ObjectMapper objectMapper;@Beanpublic SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {http.authorizeHttpRequests(request -> request.anyRequest().authenticated());http.formLogin(Customizer.withDefaults());http.csrf(AbstractHttpConfigurer::disable);http.addFilterBefore(captureCodeAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);return http.build();}public CaptureCodeAuthenticationFilter captureCodeAuthenticationFilter() {ProviderManager providerManager = new ProviderManager(new CaptureCodeAuthenticationProvider());CaptureCodeAuthenticationFilter filter =new CaptureCodeAuthenticationFilter(providerManager);filter.setAuthenticationSuccessHandler((request, response, authentication) -> {response.setStatus(HttpServletResponse.SC_OK);response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);response.getWriter().write(objectMapper.writeValueAsString(Result.ok("认证成功")));response.getWriter().flush();});filter.setAuthenticationFailureHandler((request, response, exception) -> {response.setStatus(HttpServletResponse.SC_OK);response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);response.getWriter().write(objectMapper.writeValueAsString(Result.ok("认证失败")));response.getWriter().flush();});return filter;}@Beanpublic UserDetailsService users(PasswordEncoder passwordEncoder) {UserDetails user = User.withUsername("admin").password(passwordEncoder.encode("admin")).build();return new InMemoryUserDetailsManager(user);}@Beanpublic PasswordEncoder encoder() {return new BCryptPasswordEncoder();}}
http://www.lryc.cn/news/226971.html

相关文章:

  • 某电力设计公司绩效考核优化项目成功案例纪实
  • 力扣371周赛
  • Python之字符串、正则表达式练习
  • Transmit :macOS 好用的 Ftp/SFtp 工具
  • 【Github】git clone命令下载文件中途停止
  • Clickhouse学习笔记(10)—— 查询优化
  • [量化投资-学习笔记012]Python+TDengine从零开始搭建量化分析平台-策略回测
  • MySQL 查看 event 执行记录
  • 开发知识点-Vue-Electron
  • 【线性代数】反求矩阵A
  • MyBatis 中的 foreach 的用法
  • 交叉编译 mysql-connector-c
  • 企业如何选择正确的存储服务器租用?
  • 45.跳跃游戏II
  • css style、css color 转 UIColor
  • C++(20):typename声明类的子类型的简化
  • 一个java文件的JVM之旅
  • C# wpf 实现任意控件(包括窗口)更多拖动功能
  • 一种ADC采样算法,中位值平均滤波+递推平均滤波
  • 技能培训知识付费服务预约小程序的效果如何
  • SparkSQL之Catelog体系
  • 【操作系统面试题(32道)与面试Linux命令大全】
  • Qt TCP/IP网络通信
  • 全域旅游“一机游”智慧旅游平台解决方案:PPT全文48页,附下载
  • Ubuntu 22.04 (WSL2) 安装 libssl1.1
  • Unity 跑酷游戏全部脚本(完结)
  • 凯美瑞 vs 太空船:Web3 游戏生长的两条路径
  • (一)正点原子I.MX6ULL kernel6.1移植
  • 计算机服务器中了mallox勒索病毒怎么解决,勒索病毒解密,数据恢复
  • CSS3实现动态旋转加载样式