若依登录自定义扩展Springboot+security支持密码、手机验证码登录方式

若依开源框架登录使用的配置大部分都是security自定义的,目前希望在此框架基础上支持自定义的登录,如手机号+密码登录认证、手机号+短信验证码认证。
1、自定义登录实现思路

主要是实现继承DaoAuthenticationProvider类,重写additionalAuthenticationChecks方法,将通过密码标识来判断是不是需要验证密码和免密验证。

2、继承DaoAuthenticationProvider

`import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
/**

  • 短信登陆鉴权 Provider,要求实现 AuthenticationProvider 接口
    */
    public class SmsCodeAuthenticationProvider extends DaoAuthenticationProvider {

    public SmsCodeAuthenticationProvider(UserDetailsService userDetailsService) {
    super();
    setUserDetailsService(userDetailsService);
    }

    protected void additionalAuthenticationChecks(UserDetails userDetails, UsernamePasswordAuthenticationToken authentication) throws AuthenticationException {
    if (authentication.getCredentials() == null) {
    this.logger.debug(“Authentication failed: no credentials provided”);
    throw new BadCredentialsException(this.messages.getMessage(“AbstractUserDetailsAuthenticationProvider.badCredentials”, “Bad credentials”));
    } else {
    String presentedPassword = authentication.getCredentials().toString();
    if(“CUSTOM_LOGIN_SMS”.equals(presentedPassword)){
    //短信登录,不验证密码
    }else{
    BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
    if (!passwordEncoder.matches(presentedPassword, userDetails.getPassword())) {
    this.logger.debug(“Authentication failed: password does not match stored value”);
    throw new BadCredentialsException(this.messages.getMessage(“AbstractUserDetailsAuthenticationProvider.badCredentials”, “Bad credentials”));
    }
    }
    }
    }
    }`

3、修改security配置,修改SecurityConfig中的身份验证接口,加入重写的authenticationProvider方法

/** * 身份认证接口 */ @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(new SmsCodeAuthenticationProvider(userDetailsService)); auth.userDetailsService(userDetailsService) .passwordEncoder(bCryptPasswordEncoder()); }
并添加你的登录接口匿名访问
在这里插入图片描述
4、实现登录接口

controller类,通过手机号获取到存在redis中的验证码,若获取不到则返回验证码失效

@ApiOperation("手机号+短信验证码登录") @PostMapping(value="/smslogin") public AjaxResult loginByCode(@RequestBody LoginBody body) { String realAuthCode = RedisCache.getCacheObject(REDIS_KEY_PREFIX_AUTH_CODE + body.getPhone()); if(StringUtils.isEmpty(realAuthCode)){ return AjaxResult.error("验证码失效"); } else if(!body.getCode().equals(realAuthCode)) { return AjaxResult.error("验证码错误"); } else { SysUser entity = userService.selectUserByPhone(body.getPhone()); String token = smsLoginService.login(body.getPhone(), "CUSTOM_LOGIN_SMS"); AjaxResult result = AjaxResult.success("登录成功!", entity); result.put(Constants.TOKEN, token); //登陆成功后清除redis缓存 RedisCache.deleteObject(REDIS_KEY_PREFIX_AUTH_CODE + body.getPhone()); return result; } }
5.如果你的用户表的用户名与手机号不相同则可以在UserDetailsServiceImpl中添加如下代码

@Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { SysUser user; if(Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$").matcher(username).matches()){ user = userService.selectUserByPhone(username); }else{ user = userService.selectUserByUserName(username); } if (StringUtils.isNull(user)) { log.info("登录用户:{} 不存在.", username); throw new UsernameNotFoundException("登录用户:" + username + " 不存在"); } else if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) { log.info("登录用户:{} 已被删除.", username); throw new BaseException("对不起,您的账号:" + username + " 已被删除"); } else if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { log.info("登录用户:{} 已被停用.", username); throw new BaseException("对不起,您的账号:" + username + " 已停用"); } return createLoginUser(user); }

通过正则表达式来判断传过来的是用户名还是手机号,通过不同的查询来获取用户数据

6.调用接口测试短信发送和登陆是否成功

首次发布文章,有不足之处或代码有存在问题的地方请各位指教

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值