loginDomain修正
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
// 忽略异常
|
||||
|
||||
Reference in New Issue
Block a user