禅道bug#1588修复

This commit is contained in:
gaoqr
2026-06-05 16:06:56 +08:00
parent 05c6eea837
commit e1369e7302
21 changed files with 158 additions and 15 deletions
@@ -23,6 +23,7 @@ public class GlobalErrorCodeConstants {
public static final ErrorCode NO_PERMISSION_TO_VISIT_ORG = new ErrorCode(400, "global.error.no.permission.to.visit.org");
public static final ErrorCode REQUEST_PARAM_TYPE_ERROR = new ErrorCode(400, "global.error.request.param.type.error");
public static final ErrorCode UNAUTHORIZED = new ErrorCode(401, "global.not.login");
public static final ErrorCode BE_KICKED_OUT = new ErrorCode(401, "be.kicked.out");
public static final ErrorCode FORBIDDEN = new ErrorCode(403, "global.error.no.permission");
public static final ErrorCode REQUEST_PARAM_MISSING = new ErrorCode(403, "global.error.request.param.missing");
public static final ErrorCode NOT_FOUND = new ErrorCode(404, "global.error.request.not.found");
@@ -80,6 +80,20 @@ public class CommonResult<T> implements Serializable {
return result;
}
public static <T> CommonResult<T> error(Integer code, T data, String message) {
Assert.isTrue(!GlobalErrorCodeConstants.SUCCESS.getCode().equals(code), "code 必须是错误的!");
CommonResult<T> result = new CommonResult<>();
result.code = code;
result.msg = message;
result.data = data;
String traceId = MDC.get(TRACE_ID);
if (StringUtils.hasText(traceId)) {
result.traceId = traceId;
}
return result;
}
public static <T> CommonResult<T> error(Integer code, String message, Object... args) {
Assert.isTrue(!GlobalErrorCodeConstants.SUCCESS.getCode().equals(code), "code 必须是错误的!");
CommonResult<T> result = new CommonResult<>();
@@ -13,10 +13,12 @@ import com.cf.imes.framework.web.core.handler.GlobalExceptionHandler;
import com.cf.imes.framework.web.core.util.WebFrameworkUtils;
import com.cf.imes.module.system.api.oauth2.OAuth2TokenApi;
import com.cf.imes.module.system.api.oauth2.dto.OAuth2AccessTokenCheckRespDTO;
import com.cf.imes.module.system.api.oauth2.dto.OAuth2KickOutAccessTokenRespDTO;
import com.cf.imes.module.system.api.permission.PermissionApi;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.filter.OncePerRequestFilter;
@@ -46,6 +48,9 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
private final PermissionApi permissionApi;
public static final String KICKOUT_IP = "kickoutIp";
public static final String KICKOUT_TIME = "kickoutTime";
@Override
@SuppressWarnings("NullableProblems")
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
@@ -55,8 +60,9 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
// 情况二,基于 Token 获得用户
// 注意,这里主要满足直接使用 Nginx 直接转发到 Spring Cloud 服务的场景。
String token = null;
if (loginUser == null) {
String token = SecurityFrameworkUtils.obtainAuthorization(request,
token = SecurityFrameworkUtils.obtainAuthorization(request,
securityProperties.getTokenHeader(), securityProperties.getTokenParameter());
if (CharSequenceUtil.isNotEmpty(token)) {
Integer userType = WebFrameworkUtils.getLoginUserType(request);
@@ -78,6 +84,14 @@ public class TokenAuthenticationFilter extends OncePerRequestFilter {
// 设置当前用户
if (loginUser != null) {
SecurityFrameworkUtils.setLoginUser(loginUser, request);
} else {
if (StringUtils.isNotEmpty(token)) {
OAuth2KickOutAccessTokenRespDTO kickoutToken = oauth2TokenApi.getKickoutToken(token).getCheckedData();
if (ObjectUtil.isNotNull(kickoutToken)) {
request.setAttribute(KICKOUT_IP, kickoutToken.getIp());
request.setAttribute(KICKOUT_TIME, kickoutToken.getKickTime());
}
}
}
// 继续过滤链
chain.doFilter(request, response);
@@ -1,5 +1,6 @@
package com.cf.imes.framework.security.core.handler;
import cn.hutool.core.util.ObjectUtil;
import com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.util.i18n.core.util.I18nUtils;
@@ -14,7 +15,10 @@ import jakarta.servlet.FilterChain;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.BE_KICKED_OUT;
import static com.cf.imes.framework.common.exception.enums.GlobalErrorCodeConstants.UNAUTHORIZED;
import static com.cf.imes.framework.security.core.filter.TokenAuthenticationFilter.KICKOUT_IP;
import static com.cf.imes.framework.security.core.filter.TokenAuthenticationFilter.KICKOUT_TIME;
/**
* 访问一个需要认证的 URL 资源,但是此时自己尚未认证(登录)的情况下,返回 {@link GlobalErrorCodeConstants#UNAUTHORIZED} 错误码,从而使前端重定向到登录页
@@ -29,9 +33,25 @@ public class AuthenticationEntryPointImpl implements AuthenticationEntryPoint {
@Resource
private I18nUtils i18nUtils;
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e) {
log.debug("[commence][访问 URL({}) 时,没有登录]", request.getRequestURI(), e);
Object kickoutIpObj = request.getAttribute(KICKOUT_IP);
Object kickoutTimeObj = request.getAttribute(KICKOUT_TIME);
// 被踢下线
if (ObjectUtil.isAllNotEmpty(kickoutIpObj, kickoutTimeObj)) {
String kickMsg = i18nUtils.getMessage(
BE_KICKED_OUT.getMsg(),
kickoutTimeObj,
kickoutIpObj
);
ServletUtils.writeJSON(response, CommonResult.error(UNAUTHORIZED.getCode(), kickMsg, i18nUtils.getMessage(UNAUTHORIZED.getMsg())));
return;
}
// 返回 401
ServletUtils.writeJSON(response, CommonResult.error(UNAUTHORIZED.getCode(), i18nUtils.getMessage(UNAUTHORIZED.getMsg())));
}