loginDomain修正

This commit is contained in:
2025-12-19 18:19:04 +08:00
parent 9c4f73ac9c
commit 1131a34c6e
19 changed files with 206 additions and 252 deletions

View File

@@ -17,7 +17,17 @@ import org.springframework.web.filter.OncePerRequestFilter;
import org.xyzh.common.auth.contants.AuthContants;
import java.io.IOException;
import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.fastjson2.JSON;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.dto.sys.TbSysPermissionDTO;
import org.xyzh.common.redis.service.RedisService;
/**
* @description Gateway 认证模式配置 - 信任 Gateway 传递的用户信息
@@ -30,7 +40,7 @@ import java.util.Collections;
@Configuration
@ConditionalOnProperty(name = "auth.gateway-mode", havingValue = "true")
public class GatewayAuthConfig {
private static final Logger log = LoggerFactory.getLogger(GatewayAuthConfig.class);
private static final Logger logger = LoggerFactory.getLogger(GatewayAuthConfig.class);
/**
* Gateway 信任过滤器 - 从请求头获取用户信息
@@ -38,7 +48,7 @@ public class GatewayAuthConfig {
*/
@Bean
public GatewayTrustFilter gatewayTrustFilter() {
log.info("启用 Gateway 认证模式,微服务将信任 Gateway 传递的用户信息");
logger.info("启用 Gateway 认证模式,微服务将信任 Gateway 传递的用户信息");
return new GatewayTrustFilter();
}
@@ -46,7 +56,12 @@ public class GatewayAuthConfig {
* Gateway 信任过滤器实现
*/
public static class GatewayTrustFilter extends OncePerRequestFilter {
private static final Logger log = LoggerFactory.getLogger(GatewayTrustFilter.class);
private static final Logger logger = LoggerFactory.getLogger(GatewayTrustFilter.class);
private static final String LOGIN_TOKEN_PREFIX = "login:token:";
private static final String BEARER_PREFIX = "Bearer ";
@Autowired
private RedisService redisService;
@Override
protected void doFilterInternal(@NonNull HttpServletRequest request,
@@ -59,12 +74,12 @@ public class GatewayAuthConfig {
String username = request.getHeader(AuthContants.USERNAME_ATTRIBUTE);
if (StringUtils.hasText(userId)) {
// 构造简化的 Principal使用 userId 作为身份标识)
// 注意:完整的 LoginDomain 应该从 Redis 加载,这里只是基本身份验证
// 从 Redis 获取用户权限
List<GrantedAuthority> authorities = loadUserAuthorities(request);
// 设置到 Spring Security 上下文
UsernamePasswordAuthenticationToken authentication =
new UsernamePasswordAuthenticationToken(userId, null, Collections.emptyList());
new UsernamePasswordAuthenticationToken(userId, null, authorities);
SecurityContextHolder.getContext().setAuthentication(authentication);
// 同时将用户信息设置到 request attributes 中,供业务代码使用
@@ -73,10 +88,55 @@ public class GatewayAuthConfig {
request.setAttribute(AuthContants.USERNAME_ATTRIBUTE, username);
}
log.debug("从 Gateway 获取用户信息: userId={}, username={}", userId, username);
logger.info("从 Gateway 获取用户信息: userId={}, username={}, 权限数={}", userId, username, authorities.size());
}
filterChain.doFilter(request, response);
}
/**
* 从 Redis 加载用户权限列表
*/
private List<GrantedAuthority> loadUserAuthorities(HttpServletRequest request) {
List<GrantedAuthority> authorities = new ArrayList<>();
try {
String authHeader = request.getHeader("Authorization");
logger.info("Authorization header: {}", authHeader != null ? "Bearer ***" : "null");
if (StringUtils.hasText(authHeader) && authHeader.startsWith(BEARER_PREFIX)) {
String token = authHeader.substring(BEARER_PREFIX.length());
String cacheKey = LOGIN_TOKEN_PREFIX + token;
Object obj = redisService.get(cacheKey);
logger.info("Redis key: {}, obj type: {}", cacheKey, obj != null ? obj.getClass().getName() : "null");
LoginDomain login = null;
if (obj instanceof LoginDomain) {
login = (LoginDomain) obj;
} else if (obj instanceof String) {
// Redis 返回的是 JSON 字符串,需要反序列化
login = JSON.parseObject((String) obj, LoginDomain.class);
logger.info("从 JSON 反序列化 LoginDomain");
}
if (login != null) {
if (login.getUserPermissions() != null) {
for (TbSysPermissionDTO permission : login.getUserPermissions()) {
// status 为 null 或 true 时都视为有效权限
if (permission.getCode() != null && !Boolean.FALSE.equals(permission.getStatus())) {
authorities.add(new SimpleGrantedAuthority(permission.getCode()));
}
}
}
logger.info("加载用户权限: {} 个", authorities.size());
}
}
} catch (Exception e) {
logger.warn("加载用户权限失败: {}", e.getMessage(), e);
}
return authorities;
}
}
}

View File

@@ -8,6 +8,8 @@ import org.springframework.web.context.request.ServletRequestAttributes;
import org.xyzh.common.core.domain.LoginDomain;
import org.xyzh.common.redis.service.RedisService;
import com.alibaba.fastjson2.JSON;
import jakarta.annotation.PostConstruct;
import jakarta.servlet.http.HttpServletRequest;
@@ -49,6 +51,9 @@ public class LoginUtil {
Object obj = instance.redisService.get(cacheKey);
if (obj instanceof LoginDomain) {
return (LoginDomain) obj;
} else if (obj instanceof String) {
// Redis 返回的是 JSON 字符串,需要反序列化
return JSON.parseObject((String) obj, LoginDomain.class);
}
} catch (Exception e) {
// 忽略异常