fix: 验证码校验拦截问题修复
This commit is contained in:
@@ -8,6 +8,8 @@ import org.springframework.context.annotation.Configuration;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* EasyCaptcha 配置类
|
||||
*
|
||||
* @author: haoxr
|
||||
* @date: 2023/03/24
|
||||
*/
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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";
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user