Spring Security Oauth2关于自定义登录的几种解决方案(二)

上一篇文章,通过简单的方式进行自定义用户登录授权的动作,投机取巧使用了他的内部循环处理机制,完成了我们所需要的功能,本篇将介绍一下自定义模式的登录方式(例如:原始oauth2自带的密码模式,授权码模式,简单模式,客户端模式)。最终其实我们还是采用了密码模式的思路,只是修改了两个参数而已。

本篇采用新增TokenGranter完成自定义登录

第一步:创建一个新的Token,继承AbstractAuthenticationToken

其中,Token的关键在于Authenticated是否授权,需要两个构造,一个为未鉴权Token,以及一个已鉴权Token,后续也需要判断是否为该Token,才进行相关判断

package com.example.customoauth.authentication.account;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import java.util.Collection;

/**
我个人将验证码以及密码模式封装在一起,所以传入三个参数,通过判断判断短信验证码是否为空来决定采用哪种验证方式,是密码验证还是短信验证码验证,
**/
public class AccountLoginToken extends AbstractAuthenticationToken {
   
    //用户名
    private final Object principal;
    //密码
    private Object credentials;
    //短信验证码
    private String vcode;
    /**
     * 构建一个没有鉴权的 AccountLoginToken,手机号,密码,验证码
     */
    public AccountLoginToken(Object principal, Object credentials,String vcode) {
   
        super(null);
        this.principal = principal;
        this.credentials=credentials;
        this.vcode = vcode;
        setAuthenticated(false);
    }
    /**
     * 构建拥有鉴权的 AccountLoginToken
     */
    public AccountLoginToken(Object principal, Collection<? extends GrantedAuthority> authorities) {
   
        super(authorities);
        this.principal = principal;
        // must use super, as we override
        super.setAuthenticated(true);
    }
    @Override
    public Object getCredentials() {
   
        return this.credentials;
    }
    @Override
    public Object getPrincipal() {
   
        return this.principal;
    }
    public String getVcode() {
   
        return this.vcode;
    }
}

第二步:创建AccountAuthenticationProvider,实现AuthenticationProvider

此功能在第一篇已经介绍,不过多赘述,直接贴入代码

package com.example.customoauth.authentication.account;

import com.alibaba.fastjson.JSON;
import com.yfhcloud.common.yfhutils.Constant;
import com.yfhcloud.common.yfhutils.WebResponse;
import com.yfhcloud.common.yfhutils.enums.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
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.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

/**
 * 后端短信认证校验
 * 原理:AuthenticationProvider通常按照认证请求链顺序去执行,
 * 一个返回非null响应表示程序验证通过,
 * 不再尝试验证其它的provider;如果后续提供的身份验证程序 成功地对请求进行身份认证,
 * 则忽略先前的身份验证异常及null响应,并将使用成功的身份验证。
 * 如果没有provider提供一个非null响应,或者有一个新的抛出AuthenticationException,
 * 那么最后的AuthenticationException将会抛出。
 *
 * @author : Windy
 * @version :1.0
 * @since : 2020/12/22 15:51
 */
@Component
@Slf4j
public class AccountAuthenticationProvider implements AuthenticationProvider {
   

	//这个代码我就不贴了,上一篇有,根据自身业务进行修改即可
    @Autowired
    @Qualifier("securityUserDetailsService")
    private UserDetailsService securityUserDetailsService;

	//由于使用@Autowired进行加载,似乎有冲突,暂时我默认直接在用的地方加载,第一篇那地方也需要修改以下,暂时不在config中用@bean进行初始化。
    private PasswordEncoder passwordEncoder= PasswordEncoderFactories
  • 7
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值