在 Spring Security 中定义多种登录方式,比如邮箱、手机验证码登录

前言

现在各大网站登录的方式是越来越多。比如:传统的用户名密码登录、快捷的邮箱、手机验证码登录,还有流行的第三方登录。那本篇呢,就给大家带来如何在 Spring Security 中定义使用邮箱验证码登录方式。看完本篇,让你学会自定义认证方式,如果公司还需要使用手机验证码登录,简简单单就能集成,毕竟流程是一致的。

编码

自定义验证方式需要使用到 Spring Security 内置的几个对象,如果各位还不了解,可以先看看这篇文章:Spring Security 中重要对象汇总

用户名密码表单登录会进入到 UsernamePasswordAuthenticationFilter。在这整个类中,还会用到一个对象 UsernamePasswordAuthenticationToken

  • AbstractAuthenticationProcessingFilter
  • AbstractAuthenticationToken

EmailVerificationCodeAuthenticationFilter

参考 UsernamePasswordAuthenticationFilter(copy)类并进行删减, 定义 EmailVerificationCodeAuthenticationFilter 类,内容如下:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
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 org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author cxyxj
 */
public class EmailVerificationCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

    /**
     * 默认的请求参数名称
     */
    public static final String EMAIL_KEY = "email";
    public static final String EMAIL_CODE_KEY = "emailCode";

    private String emailParameter = EMAIL_KEY;
    private String emailCodeParameter = EMAIL_CODE_KEY;
    /**
     * 是否仅支持post方式
     */
    private boolean postOnly = true;


    /**
     * 对请求进行过滤,只有接口为 /emil-login,请求方式为 POST,才会进入逻辑
     */
    public EmailVerificationCodeAuthenticationFilter() {
        super(new AntPathRequestMatcher("/email-login", "POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException, IOException, ServletException {
        // 需要是 POST 请求
        if (postOnly &&  !request.getMethod().equals("POST")) {
            throw new AuthenticationServiceException(
                    "Authentication method not supported: " + request.getMethod());
        }
        // 判断请求格式是否 JSON
        if (request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE)) {
            Map<String, String> loginData = new HashMap<>(2);
            try {
                loginData = new ObjectMapper().readValue(request.getInputStream(), Map.class);
            } catch (IOException e) {
                throw new InternalAuthenticationServiceException("请求参数异常");
            }
            // 获得请求参数
            String email = loginData.get(emailParameter);
            String emailCode = loginData.get(emailCodeParameter);
            // 检查验证码
            checkEmailCode(emailCode);
            if(StringUtils.isEmpty(email)){
                throw new AuthenticationServiceException("邮箱不能为空");
            }
            /**
             * 使用请求参数传递的邮箱和验证码,封装为一个未认证 EmailVerificationCodeAuthenticationToken 身份认证对象,
             * 然后将该对象交给 AuthenticationManager 进行认证
             */
            EmailVerificationCodeAuthenticationToken authRequest = new EmailVerificationCodeAuthenticationToken(email);
            setDetails(request, authRequest);
            return this.getAuthenticationManager().authenticate(authRequest);
        }
        return null;
    }

    public void setDetails(HttpServletRequest request , EmailVerification
  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值