From 958f5253dfd6bd7896968569b262c41eb584af68 Mon Sep 17 00:00:00 2001 From: "Luke.Ye" Date: Tue, 24 Mar 2026 11:52:02 +0800 Subject: [PATCH] opt --- .../north/controller/UserQueryController.java | 116 ++++++++++++++++-- 1 file changed, 104 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/knowledge/base/infrastructure/north/controller/UserQueryController.java b/src/main/java/com/knowledge/base/infrastructure/north/controller/UserQueryController.java index 97aa92c..f559541 100644 --- a/src/main/java/com/knowledge/base/infrastructure/north/controller/UserQueryController.java +++ b/src/main/java/com/knowledge/base/infrastructure/north/controller/UserQueryController.java @@ -36,24 +36,41 @@ public class UserQueryController { @GetMapping("/check") public ResponseEntity check( + @RequestHeader(value = "X-Auth-Token", required = false) String forwardedToken, @CookieValue(value = ConstantConfig.COOKIE_KEY, required = false) String cookieToken, @RequestHeader(value = "Authorization", required = false) String headerToken, + @RequestHeader(value = "Cookie", required = false) String rawCookie, @RequestHeader(value = "X-Original-URI", required = false) String originalUri, @RequestHeader(value = "X-Original-HOST", required = false, defaultValue = StrUtil.EMPTY) String host ) { - String token = headerToken != null ? headerToken : cookieToken; - originalUri = URLDecoder.decode(originalUri, StandardCharsets.UTF_8); + originalUri = URLDecoder.decode( + originalUri == null ? StrUtil.EMPTY : originalUri, + StandardCharsets.UTF_8 + ); - LOGGER.info("[权限校验] token={}, host={}, originalUri={}", headerToken != null ? headerToken : cookieToken, host, originalUri); + String token = firstNonBlank( + forwardedToken, + normalizeAuthorization(headerToken), + cookieToken, + extractCookie(rawCookie, ConstantConfig.COOKIE_KEY) + ); - if (token == null || token.isBlank()) { + LOGGER.info("[权限校验] token={}, host={}, originalUri={}, rawCookieExists={}", + maskToken(token), host, originalUri, StrUtil.isNotBlank(rawCookie)); + + if (StrUtil.isBlank(token)) { LOGGER.warn("[权限校验] 未提供token,拒绝访问"); return ResponseEntity.status(401).body(Map.of("code", 401, "msg", "未授权")); } - Optional userTokenOpt = userAppService.findToken(token); + Optional userTokenOpt = null; + try { + userTokenOpt = userAppService.findToken(token); + } catch (Exception e) { + LOGGER.error("userAppService.findToken(token) error", e); + } if (userTokenOpt.isEmpty()) { - LOGGER.warn("[权限校验] token无效: {}", token); + LOGGER.warn("[权限校验] token无效: {}", maskToken(token)); return ResponseEntity.status(401).body(Map.of("code", 401, "msg", "无效token")); } @@ -61,7 +78,7 @@ public class UserQueryController { LOGGER.info("[权限校验] 解析到userId={}", userId); // os的权限校验很简单,token有效即可 - if(ConstantConfig.OS_HOST.equals(host)) { + if (ConstantConfig.OS_HOST.equals(host)) { LOGGER.info("[权限校验] 访问通过: userId={}, host={}, uri={}", userId, host, originalUri); return ResponseEntity.ok(Map.of("code", 0, "msg", "权限校验通过")); } @@ -84,7 +101,9 @@ public class UserQueryController { for (Long roleId : roleIds) { List rules = userAppService.listRoleFileRules(roleId); LOGGER.info("[权限校验] 角色[{}]规则数={}", roleId, rules != null ? rules.size() : 0); - if (rules != null) allRules.addAll(rules); + if (rules != null) { + allRules.addAll(rules); + } } Optional userDTO = userAppService.findById(userId); @@ -93,12 +112,14 @@ public class UserQueryController { boolean hasPermission = false; for (RoleFileRuleDTO rule : allRules) { String pattern = rule.getFilePattern(); - if (pattern == null) continue; + if (StrUtil.isBlank(pattern)) { + continue; + } - LOGGER.info("[权限校验] 开始判断用户[{}]的角色规则[{}]是否允许访问: {}", userId, pattern, originalUri); + LOGGER.info("[权限校验] 开始判断用户[{}]的角色规则[{}]是否允许访问: {}", userId, pattern, originalUri); // 动态替换占位符 - if (pattern.contains("${username}") && userName != null) { + if (pattern.contains("${username}") && StrUtil.isNotBlank(userName)) { pattern = pattern.replace("${username}", userName); } @@ -110,7 +131,18 @@ public class UserQueryController { } // 先前缀匹配,再正则匹配 - if (originalUri.startsWith(pattern) || originalUri.matches(pattern)) { + boolean matched = false; + if (originalUri.startsWith(pattern)) { + matched = true; + } else { + try { + matched = originalUri.matches(pattern); + } catch (Exception e) { + LOGGER.warn("[权限校验] 规则正则非法,跳过。pattern={}, err={}", pattern, e.getMessage()); + } + } + + if (matched) { LOGGER.info("[权限校验] 用户[{}]的角色规则[{}]允许访问: {}", userId, pattern, originalUri); hasPermission = true; break; @@ -126,6 +158,66 @@ public class UserQueryController { } } + private String firstNonBlank(String... values) { + if (values == null || values.length == 0) { + return null; + } + for (String value : values) { + if (StrUtil.isNotBlank(value)) { + return value.trim(); + } + } + return null; + } + + private String normalizeAuthorization(String authorization) { + if (StrUtil.isBlank(authorization)) { + return null; + } + String value = authorization.trim(); + if (value.regionMatches(true, 0, "Bearer ", 0, 7)) { + return value.substring(7).trim(); + } + return value; + } + + private String extractCookie(String rawCookie, String cookieName) { + if (StrUtil.isBlank(rawCookie) || StrUtil.isBlank(cookieName)) { + return null; + } + + String[] pairs = rawCookie.split(";"); + for (String pair : pairs) { + if (StrUtil.isBlank(pair)) { + continue; + } + + String item = pair.trim(); + int idx = item.indexOf('='); + if (idx <= 0) { + continue; + } + + String name = item.substring(0, idx).trim(); + String value = item.substring(idx + 1).trim(); + if (cookieName.equals(name)) { + return value; + } + } + + return null; + } + + private String maskToken(String token) { + if (StrUtil.isBlank(token)) { + return StrUtil.EMPTY; + } + if (token.length() <= 8) { + return "****"; + } + return token.substring(0, 4) + "****" + token.substring(token.length() - 4); + } + @GetMapping("/username") public ResponseEntity getUsernameByToken( @CookieValue(value = ConstantConfig.COOKIE_KEY, required = false) String cookieToken,