security模仿密码登录实现短信验证码登录
security模仿密码登录实现短信验证码登录
- 模仿UsernamePasswordAuthenticationToken创建短信验证码的token类SmsAuthenticationToken
/*** 手机验证码认证token** @author shipc* @date 2021/12/13 21:22*/
public class SmsAuthenticationToken extends AbstractAuthenticationToken {private static final long serialVersionUID = 531L;/*** 手机号 | 用户信息*/private final Object principal;/*** 验证码*/private Object credentials;public SmsAuthenticationToken(Object principal, Object credentials) {super(null);this.principal = principal;this.credentials = credentials;this.setAuthenticated(false);}public SmsAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {super(authorities);this.principal = principal;this.credentials = credentials;this.setAuthenticated(true);}@Overridepublic Object getCredentials() {return credentials;}@Overridepublic Object getPrincipal() {return principal;}@Overridepublic void eraseCredentials() {super.eraseCredentials();this.credentials = null;}
}
- 模仿UsernamePasswordAuthenticationFilter创建处理短信验证码的过滤器
public class UsernamePasswordAuthenticationFilter extends AbstractAuthenticationProcessingFilter {public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "username";public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "password";private String usernameParameter = "username";private String passwordParameter = "password";private boolean postOnly = true;public UsernamePasswordAuthenticationFilter() {super(new AntPathRequestMatcher("/login", "POST"));}public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {if (this.postOnly && !request.getMethod().equals("POST")) {throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());} else {String username = this.obtainUsername(request);String password = this.obtainPassword(request);username = username.trim();UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);this.setDetails(request, authRequest);return this.getAuthenticationManager().authenticate(authRequest);}}@Nullableprotected String obtainPassword(HttpServletRequest request) {return request.getParameter(this.passwordParameter);}@Nullableprotected String obtainUsername(HttpServletRequest request) {return request.getParameter(this.usernameParameter);}protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {authRequest.setDetails(this.authenticationDetailsSource.buildDetails(request));}public void setUsernameParameter(String usernameParameter) {Assert.hasText(usernameParameter, "Username parameter must not be empty or null");this.usernameParameter = usernameParameter;}public void setPasswordParameter(String passwordParameter) {Assert.hasText(passwordParameter, "Password parameter must not be empty or null");this.passwordParameter = passwordParameter;}public void setPostOnly(boolean postOnly) {this.postOnly = postOnly;}public final String getUsernameParameter() {return this.usernameParameter;}public final String getPasswordParameter() {return this.passwordParameter;}
}
- 模仿DaoAuthenticationProvider创建处理SmsAuthenticationToken的Provider
/*** 短信验证登录provider** @author shipc* @date 2021/12/13 21:47*/
public class SmsAuthenticationProvider implements AuthenticationProvider {private SmsUserDetailsService userDetailsService;@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException {final SmsAuthenticationToken smsAuthenticationToken = (SmsAuthenticationToken) authentication;final String mobile = smsAuthenticationToken.getPrincipal() == null ? "" :smsAuthenticationToken.getPrincipal().toString();final String code = smsAuthenticationToken.getCredentials().toString();if (code == null) {throw new SmsAuthenticationException(SmsAuthenticationHandler.AuthenticationStatus.NO_VERIFY_CODE);}checkSmsCode(mobile, code);// 根据手机号获取用户信息final UserDetails userDetails = userDetailsService.loadUserByUsername(mobile);return createSuccessAuthenticationToken(smsAuthenticationToken, userDetails);}private SmsAuthenticationToken createSuccessAuthenticationToken(SmsAuthenticationToken smsAuthenticationToken, UserDetails userDetails) {// 验证成功后,构造一个已经认证的token并返回final SmsAuthenticationToken authenticationToken = new SmsAuthenticationToken(userDetails, null, userDetails.getAuthorities());authenticationToken.setDetails(smsAuthenticationToken.getDetails());return authenticationToken;}public void setUserDetailsService(SmsUserDetailsService userDetailsService) {this.userDetailsService = userDetailsService;}/*** 校验手机号和验证码* @param mobile 手机号* @param code 验证码*/private void checkSmsCode(String mobile, String code) {final boolean flag = userDetailsService.checkSmsCode(mobile, code);if (!flag) {throw new SmsAuthenticationException(SmsAuthenticationHandler.AuthenticationStatus.BAD_VERIFY_CODE);}}@Overridepublic boolean supports(Class<?> aClass) {return SmsAuthenticationToken.class.isAssignableFrom(aClass);}
}
- 模仿UserDetailsService
/*** 手机号验证码用户service** @author shipc* @date 2021/12/15 00:22*/
public interface SmsUserDetailsService extends UserDetailsService {/*** 校验验证码* @param mobile 手机号* @param code 验证码* @return true/false*/boolean checkSmsCode(String mobile, String code);
}
- 创建配置类SmsCodeAuthenticationSecurityConfig
/*** 手机验证码认证配置** @author shipc* @date 2021/12/13 22:43*/
@Configuration
public class SmsCodeAuthenticationSecurityConfig extends SecurityConfigurerAdapter<DefaultSecurityFilterChain, HttpSecurity> {@Autowiredprivate SmsAuthenticationHandler smsAuthenticationHandler;@Autowiredprivate MobileUserDetailsServiceImpl mobileUserDetailsService;@Overridepublic void configure(HttpSecurity http) throws Exception {final SmsCodeAuthenticationFilter smsCodeAuthenticationFilter = new SmsCodeAuthenticationFilter();// 设置 authenticationManager, 不设置 认证流程会断掉smsCodeAuthenticationFilter.setAuthenticationManager(http.getSharedObject(AuthenticationManager.class));// 扩展认证信息smsCodeAuthenticationFilter.setAuthenticationDetailsSource(new ExtendWebAuthenticationDetailsSource());// 设置认证成功处理器smsCodeAuthenticationFilter.setAuthenticationSuccessHandler(smsAuthenticationHandler);// 设置认证失败处理器smsCodeAuthenticationFilter.setAuthenticationFailureHandler(smsAuthenticationHandler);final SmsAuthenticationProvider smsAuthenticationProvider = new SmsAuthenticationProvider();smsAuthenticationProvider.setUserDetailsService(mobileUserDetailsService);// 将短信验证过滤器添加到 security 中http.authenticationProvider(smsAuthenticationProvider).addFilterAfter(smsCodeAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);}
}
- 创建配置类WebSecurityConfig继承WebSecurityConfigurerAdapter,实现void configure(HttpSecurity http)方法。
@Overrideprotected void configure(HttpSecurity http) throws Exception {// ---- 其他省略// 应用短信验证码登录http.apply(smsCodeAuthenticationSecurityConfig);http.csrf().disable();}
security模仿密码登录实现短信验证码登录相关推荐
- 2.vue3医疗在线问诊项目 - _登录模块 ==> 代码片段、css变量主题定制、cp-nav-bar组件封装、svg打包精灵图插件、cp-icon组件封装、表单校验、密码登录、短信验证码登录及两者
2.医疗在线问诊项目 - _登录模块 ==> 代码片段.css变量主题定制.cp-nav-bar组件封装.svg打包精灵图插件.cp-icon组件封装.表单校验.密码登录.短信验证码登录及两者的 ...
- Spring Security OAuth2 优雅的集成短信验证码登录以及第三方登录
基于SpringCloud做微服务架构分布式系统时,OAuth2.0作为认证的业内标准,Spring Security OAuth2也提供了全套的解决方案来支持在Spring Cloud/Spring ...
- Vue_注册登录(短信验证码登录)
一.前言 1.动态获取图片验证码 2.实现手机验证码登录(工具准备) 3.手机验证码登录(后台实现) 3.前台实现 二.主要内容 1.动态获取图片验证码 (1)请求的接口如下,返回的是一张svg的图片 ...
- 若依RuoYi整合短信验证码登录
背景:若依默认使用账号密码进行登录,但是咱们客户需要增加一个短信登录功能,即在不更改原有账号密码登录的基础上,整合短信验证码登录. 一.自定义短信登录 token 验证 仿照 UsernamePass ...
- 网上银行App登录使用短信验证码,属不属于超范围收集用户信息?
网上银行App登录该不该用短信验证码? 全国信息安全标准化技术委员会日前公布<信息安全技术 移动互联网应用(App)收集个人信息基本规范(草案)>,面向社会公开征求意见. 该标准明确了移动 ...
- 5.Spring Security 短信验证码登录
Spring Security 短信验证码登录 在 Spring Security 添加图形验证码一节中,我们已经实现了基于 Spring Boot + Spring Security 的账号密码登录 ...
- Spring Security 短信验证码登录(5)
在Spring Security添加图形验证码中,我们已经实现了基于Spring Boot + Spring Security的账号密码登录,并集成了图形验证码功能.时下另一种非常常见的网站登录方式为 ...
- Spring Security简单增加短信验证码登录
查网上资料增加短信验证码登录都要增加一大推,要重头写Spring Security的实现,我呢,只想在原来的密码登录基础上简单实现一下短信验证码登录. 1.首先得先一个认证类,来认证验证码是否正确,这 ...
- Abp Core 添加短信验证码登录(动态密码登录)
交流QQ群:555913397 有什么问题可以加群大家一起交流 Abp Core 添加短信验证码登录(动态密码登录) 现目前我国网站的已经很少使用电子邮箱了,基本上都是手机号作为账号,有时候粗心的用户 ...
最新文章
- java.io几种读写文件的方式
- python中编写函数素数_如何用Python编写素数程序?
- CVE-2018-8120 Windows权限提升
- 磁盘剩余空间策略_如何无损扩展C盘空间大小,这一招足够!
- java as uuid_java UUID 源码学习
- 光纤跳线的交叉连接注意点?
- papers to read
- iOS开发-停止WebView播放视频/音频
- jquery发送ajax请求返回数据格式
- wordpress获取各类页面链接的函数总结
- Windows下IIS搭建Ftp服务器
- Unity3D中Grid Layout Group组件一键实现自动排版Image
- 油猴脚本(tampermonkey):百度网盘搜索引擎聚合
- deep-text-recognition-benchmark 项目训练data.mdb数据集,运行日志中,只显示训练了英文和数字
- 工业物联网盒子python_【工业4.0面面观】之十八:基于AWS的工业物联网应用案例...
- RHCE证书考试报名流程
- 新概念英语第三册51-60课(转)
- matlab计算铰接式履带车辆转向性能
- 【PHP】linux搭建PHP运行环境
- SQLite安装配置详细教程2023版