SpringBoot+MyBatis-plus+SpringSecurity+JWT 验证码认证

论坛 期权论坛     
选择匿名的用户   2021-5-26 12:32   419   0
<p>本文基于<a href="https://blog.csdn.net/zhouzhiwengang/article/details/112556678">SpringBoot&#43;MyBatis-plus&#43;SpringSecurity&#43;JWT 登入认证,实现前后端分离</a>基础之上追加验证码登入认证功能。</p>
<h2>1、springsecurity 验证码模式核心代码</h2>
<h3>创建验证码过滤器</h3>
<p>在filter中增加VerificationCodeLoginFilter。这里过滤的是”/auth/code”的请求,用不同的请求地址来区分不同的登录认证方式。</p>
<pre class="blockcode"><code>package com.digipower.sercurity.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import com.digipower.common.entity.Result;
import com.digipower.sercurity.entity.JwtUserDetails;
import com.digipower.sercurity.token.VerificationCodeAuthenticationToken;
import com.digipower.sercurity.util.JwtTokenUtil;
import com.fasterxml.jackson.databind.ObjectMapper;

public class VerificationCodeLoginFilter extends AbstractAuthenticationProcessingFilter {
public static final String SPRING_SECURITY_FORM_USERNAME_KEY &#61; &#34;username&#34;;
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY &#61; &#34;password&#34;;
public static final String SPRING_SECURITY_FORM_CODE_KEY &#61; &#34;code&#34;;

private String usernameParameter &#61; SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter &#61; SPRING_SECURITY_FORM_PASSWORD_KEY;
private String codeParameter &#61; SPRING_SECURITY_FORM_CODE_KEY;


/**
  * 是否仅 POST 方式
  */
private boolean postOnly &#61; true;

  /**
     * 获取授权管理, 创建VerificationCodeLoginFilter时获取
     */
    private AuthenticationManager authenticationManager;


public VerificationCodeLoginFilter(String defaultFilterProcessesUrl,AuthenticationManager authenticationManager) {

  super(new AntPathRequestMatcher(defaultFilterProcessesUrl, &#34;POST&#34;));
  this.authenticationManager &#61; authenticationManager;
}

&#64;Override
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
   throws AuthenticationException, IOException, ServletException {
  // TODO Auto-generated method stub
  if (postOnly &amp;&amp; !request.getMethod().equals(&#34;POST&#34;)) {
   throw new AuthenticationServiceException(&#34;Authentication method not supported: &#34; &#43; request.getMethod());
  }

  String username &#61; obtainUsername(request);
  String password &#61; obtainPassword(request);
  String code &#61; obtainCode(request);

  if (username &#61;&#61; null) {
   username &#61; &#34;&#34;;
  }

  if (password &#61;&#61; null) {
   password &#61; &#34;&#34;;
  }

  if (code &#61;&#61; null) {
   code &#61; &#34;&#34;;
  }

  username &#61; username.trim();
  code &#61; code.trim();

  VerificationCodeAuthenticationToken authRequest &#61; new VerificationCodeAuthenticationToken(username, password,
    code);

  // Allow subclasses to set the &#34;details&#34; property
  setDetails(request, authRequest);

  return authenticationManager.authenticate(authRequest);
}

protected String obtainPassword(HttpServletRequest request) {
  return request.getParameter(passwordParameter);
}

protected String obtainUsername(HttpServletRequest request) {
  return request.getParameter(usernameParameter);
}

protected String obtainCode(HttpServletRequest request) {
  return request.getParameter(codeParameter);
}

protected void setDetails(HttpServletRequest request, VerificationCodeAuthenticationToken authRequest) {
  authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}

/**
  * TODO 一旦调用 springSecurity认证登录成功,立即执行该方法
  *
  * &#64;param request
  * &#64;param response
  * &#64;param chain
  * &#64;param authResult
  * &#64;throws IOException
  * &#64;throws ServletException
  */
&#64;Override
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain,
   Authentication authResult) throws IOException {

  // 生成jwt,并返回
  VerificationCodeAuthenticationToken token &#61; (VerificationCodeAuthenticationToken)authResult;
  JwtUserDetails userEntity &#61; new JwtUserDetails();
  if(token.getPrincipal() !&#61; null){
   userEntity.setUserName(String.valueOf(token.getPrincipal()));
  }
  if(token.getAuthorities() !&#61; null &amp;&amp; token.getAuthorities().size() &gt; 0){
   userEntity.setAuthorities(token.getAuthorities());
  }
  if(token.getCredentials() !&#61; null){
   userEntity.setPassword(String.valueOf(token.getCredentials()));
  }
  String jwtToken &#61; JwtTok
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:3875789
帖子:775174
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP