fix: 验证码校验拦截问题修复

This commit is contained in:
haoxr
2023-03-25 01:14:42 +08:00
parent 28a47319ba
commit 49f18e4a18
5 changed files with 55 additions and 35 deletions

View File

@@ -8,6 +8,8 @@ import org.springframework.context.annotation.Configuration;
import java.awt.*;
/**
* EasyCaptcha 配置类
*
* @author: haoxr
* @date: 2023/03/24
*/

View File

@@ -1,5 +1,6 @@
package com.youlai.system.framework.security.config;
import com.youlai.system.framework.security.constant.SecurityConstants;
import com.youlai.system.framework.security.filter.JwtAuthenticationFilter;
import com.youlai.system.framework.security.exception.MyAccessDeniedHandler;
import com.youlai.system.framework.security.exception.MyAuthenticationEntryPoint;
@@ -43,27 +44,27 @@ public class SecurityConfig {
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeHttpRequests()
.requestMatchers(SecurityConstants.LOGIN_PATH).permitAll() // 登录接口放行但会走过滤器链-验证码校验
.anyRequest().authenticated()
.and()
.formLogin()
.loginProcessingUrl("/api/v1/auth/login").permitAll()
.and()
.exceptionHandling()
.authenticationEntryPoint(myAuthenticationEntryPoint)
.accessDeniedHandler(myAccessDeniedHandler)
;
// disable cache
http.headers().cacheControl();
// 验证码校验过滤器
http.addFilterAt(new VerifyCodeFilter(),UsernamePasswordAuthenticationFilter.class);
http.addFilterBefore(new VerifyCodeFilter(),UsernamePasswordAuthenticationFilter.class);
// JWT 校验过滤器
http.addFilterBefore(new JwtAuthenticationFilter(jwtTokenManager), UsernamePasswordAuthenticationFilter.class);
return http.build();
}
/**
* 不走过滤器链的放行配置
*
* @return
*/
@Bean
public WebSecurityCustomizer webSecurityCustomizer() {
return (web) -> web.ignoring()

View File

@@ -0,0 +1,16 @@
package com.youlai.system.framework.security.constant;
/**
* Security 常量
*
* @author: haoxr
* @date: 2023/03/24
*/
public interface SecurityConstants {
/**
* 登录接口路径
*/
String LOGIN_PATH = "/api/v1/auth/login";
}

View File

@@ -4,6 +4,7 @@ import cn.hutool.core.util.StrUtil;
import com.youlai.system.common.result.ResultCode;
import com.youlai.system.common.util.ResponseUtils;
import com.youlai.system.framework.security.JwtTokenManager;
import com.youlai.system.framework.security.constant.SecurityConstants;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
@@ -23,8 +24,6 @@ import java.io.IOException;
*/
public class JwtAuthenticationFilter extends OncePerRequestFilter {
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/api/v1/auth/login", "POST");
private static final String TOKEN_PREFIX = "Bearer ";
private final JwtTokenManager tokenManager;
@@ -35,28 +34,27 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
if (DEFAULT_ANT_PATH_REQUEST_MATCHER.matches(request)) {
// 登录接口放行
if (SecurityConstants.LOGIN_PATH.equals(request.getRequestURI())) {
// 登录接口放行
chain.doFilter(request, response);
return;
}
}else{
String jwt = resolveToken(request);
if (StrUtil.isNotBlank(jwt) && SecurityContextHolder.getContext().getAuthentication() == null) {
try {
// 验证JWT
this.tokenManager.validateToken(jwt);
String jwt = resolveToken(request);
if (StrUtil.isNotBlank(jwt) && SecurityContextHolder.getContext().getAuthentication() == null) {
try {
// 验证JWT
this.tokenManager.validateToken(jwt);
// JWT验证有效获取Authentication存入Security上下文
Authentication authentication = this.tokenManager.getAuthentication(jwt);
SecurityContextHolder.getContext().setAuthentication(authentication);
// JWT验证有效获取Authentication存入Security上下文
Authentication authentication = this.tokenManager.getAuthentication(jwt);
SecurityContextHolder.getContext().setAuthentication(authentication);
chain.doFilter(request, response);
}catch (Exception e){
chain.doFilter(request, response);
}catch (Exception e){
ResponseUtils.writeErrMsg(response, ResultCode.TOKEN_INVALID);
}
}else{
ResponseUtils.writeErrMsg(response, ResultCode.TOKEN_INVALID);
}
}else{
ResponseUtils.writeErrMsg(response, ResultCode.TOKEN_INVALID);
}
}

View File

@@ -6,13 +6,13 @@ import cn.hutool.extra.spring.SpringUtil;
import com.youlai.system.common.constant.CacheConstants;
import com.youlai.system.common.result.ResultCode;
import com.youlai.system.common.util.ResponseUtils;
import com.youlai.system.framework.security.constant.SecurityConstants;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@@ -25,10 +25,6 @@ import java.io.IOException;
*/
public class VerifyCodeFilter extends OncePerRequestFilter {
/**
* 拦截路径
*/
private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/api/v1/auth/login", "POST");
public static final String VERIFY_CODE = "verifyCode";
public static final String VERIFY_CODE_KEY = "verifyCodeKey";
@@ -40,13 +36,17 @@ public class VerifyCodeFilter extends OncePerRequestFilter {
@Override
public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
if (!DEFAULT_ANT_PATH_REQUEST_MATCHER.matches(request)) {
// 非登录接口放行
chain.doFilter(request, response);
} else {
// 检验登录接口的验证码
if (SecurityConstants.LOGIN_PATH.equals(request.getRequestURI())) {
// 请求中的验证码
String requestVerifyCode = request.getParameter(VERIFY_CODE);
// TODO 兼容 2.0.0 无验证码版本,后续移除
if (StrUtil.isBlank(requestVerifyCode)) {
// 非登录接口放行
chain.doFilter(request, response);
return;
}
// 缓存中的验证码
String verifyCodeKey = request.getParameter(VERIFY_CODE_KEY);
Object cacheVerifyCode = redisTemplate.opsForValue().get(CacheConstants.VERIFY_CODE_CACHE_PREFIX + verifyCodeKey);
@@ -60,6 +60,9 @@ public class VerifyCodeFilter extends OncePerRequestFilter {
ResponseUtils.writeErrMsg(response, ResultCode.VERIFY_CODE_ERROR);
}
}
} else {
// 非登录接口放行
chain.doFilter(request, response);
}
}