添加权限校验
This commit is contained in:
parent
7886ec3267
commit
c491ab9cc2
20
config/mysql/dml.txt
Normal file
20
config/mysql/dml.txt
Normal file
@ -0,0 +1,20 @@
|
||||
INSERT INTO role (role_code, role_name) VALUES ('ADMIN', '管理员');
|
||||
INSERT INTO role (role_code, role_name) VALUES ('USER', '普通用户');
|
||||
INSERT INTO role (role_code, role_name) VALUES ('GUEST', '访客');
|
||||
|
||||
|
||||
-- 管理员全部可看
|
||||
INSERT INTO role_file_rule (role_id, file_pattern, remark) VALUES
|
||||
(1, '/', '管理员可访问所有文件');
|
||||
-- 普通用户可访问自己目录和公共目录
|
||||
INSERT INTO role_file_rule (role_id, file_pattern, remark) VALUES
|
||||
(2, '/public/${username}-', '用户可访问以用户名开头的文件');
|
||||
INSERT INTO role_file_rule (role_id, file_pattern, remark) VALUES
|
||||
(2, '/public/2025年', '用户可访问公共文件');
|
||||
-- 访客只能访问公共目录
|
||||
INSERT INTO role_file_rule (role_id, file_pattern, remark) VALUES
|
||||
(3, '/public/2025年', '访客可访问公共文件');
|
||||
|
||||
---- 为用户赋予权限 ----
|
||||
INSERT INTO user_role (user_id, role_id) values ('1', '1');
|
||||
INSERT INTO user_role (user_id, role_id) values ('2', '2');
|
||||
@ -1,14 +1,20 @@
|
||||
package com.knowledge.base.infrastructure.north.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.knowledge.base.application.service.UserAppService;
|
||||
import com.knowledge.base.infrastructure.config.ConstantConfig;
|
||||
import com.knowledge.base.infrastructure.north.dto.role.RoleFileRuleDTO;
|
||||
import com.knowledge.base.infrastructure.north.dto.role.UserRoleDTO;
|
||||
import com.knowledge.base.infrastructure.north.dto.user.UserDTO;
|
||||
import com.knowledge.base.infrastructure.north.dto.user.UserTokenDTO;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@ -18,20 +24,93 @@ import java.util.Optional;
|
||||
@RequiredArgsConstructor
|
||||
public class UserQueryController {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(UserQueryController.class);
|
||||
|
||||
private final UserAppService userAppService;
|
||||
|
||||
@GetMapping("/check")
|
||||
public ResponseEntity<?> check(
|
||||
@CookieValue(value = ConstantConfig.COOKIE_KEY, required = false) String cookieToken,
|
||||
@RequestHeader(value = "Authorization", required = false) String headerToken
|
||||
@RequestHeader(value = "Authorization", required = false) String headerToken,
|
||||
HttpServletRequest request
|
||||
) {
|
||||
String token = headerToken != null ? headerToken : cookieToken;
|
||||
if (userAppService.isValidToken(token)) {
|
||||
return ResponseEntity.ok(Map.of("code", 0, "msg", "校验成功"));
|
||||
}
|
||||
String requestUri = request.getRequestURI();
|
||||
|
||||
LOGGER.info("[权限校验] token={}, uri={}", token, requestUri);
|
||||
|
||||
if (token == null || token.isBlank()) {
|
||||
LOGGER.warn("[权限校验] 未提供token,拒绝访问");
|
||||
return ResponseEntity.status(401).body(Map.of("code", 401, "msg", "未授权"));
|
||||
}
|
||||
|
||||
Optional<UserTokenDTO> userTokenOpt = userAppService.findToken(token);
|
||||
if (userTokenOpt.isEmpty()) {
|
||||
LOGGER.warn("[权限校验] token无效: {}", token);
|
||||
return ResponseEntity.status(401).body(Map.of("code", 401, "msg", "无效token"));
|
||||
}
|
||||
|
||||
Long userId = userTokenOpt.get().getUserId();
|
||||
LOGGER.info("[权限校验] 解析到userId={}", userId);
|
||||
|
||||
// 查询用户角色
|
||||
List<UserRoleDTO> userRoles = userAppService.listUserRoles(userId);
|
||||
if (userRoles == null || userRoles.isEmpty()) {
|
||||
LOGGER.warn("[权限校验] 用户[{}]未分配任何角色", userId);
|
||||
return ResponseEntity.status(403).body(Map.of("code", 403, "msg", "无角色权限"));
|
||||
}
|
||||
|
||||
List<Long> roleIds = Lists.newArrayList();
|
||||
for (UserRoleDTO userRole : userRoles) {
|
||||
roleIds.add(userRole.getRoleId());
|
||||
}
|
||||
LOGGER.info("[权限校验] 用户[{}]拥有角色: {}", userId, roleIds);
|
||||
|
||||
// 合并所有角色的规则
|
||||
List<RoleFileRuleDTO> allRules = Lists.newArrayList();
|
||||
for (Long roleId : roleIds) {
|
||||
List<RoleFileRuleDTO> rules = userAppService.listRoleFileRules(roleId);
|
||||
LOGGER.info("[权限校验] 角色[{}]规则数={}", roleId, rules != null ? rules.size() : 0);
|
||||
if (rules != null) allRules.addAll(rules);
|
||||
}
|
||||
|
||||
Optional<UserDTO> userDTO = userAppService.findById(userId);
|
||||
String userName = userDTO.isPresent() ? userDTO.get().getUsername() : StrUtil.EMPTY;
|
||||
|
||||
boolean hasPermission = false;
|
||||
for (RoleFileRuleDTO rule : allRules) {
|
||||
String pattern = rule.getFilePattern();
|
||||
if (pattern == null) continue;
|
||||
|
||||
// 动态替换占位符
|
||||
if (pattern.contains("${username}") && userName != null) {
|
||||
pattern = pattern.replace("${username}", userName);
|
||||
}
|
||||
|
||||
// 管理员全访问(pattern为/ 或 pattern为.* 都放行)
|
||||
if ("/".equals(pattern) || ".*".equals(pattern)) {
|
||||
LOGGER.info("[权限校验] 用户[{}]的角色规则[{}]允许全路径访问: {}", userId, pattern, requestUri);
|
||||
hasPermission = true;
|
||||
break;
|
||||
}
|
||||
|
||||
// 先前缀匹配,再正则匹配
|
||||
if (requestUri.startsWith(pattern) || requestUri.matches(pattern)) {
|
||||
LOGGER.info("[权限校验] 用户[{}]的角色规则[{}]允许访问: {}", userId, pattern, requestUri);
|
||||
hasPermission = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasPermission) {
|
||||
LOGGER.info("[权限校验] 访问通过: userId={}, uri={}", userId, requestUri);
|
||||
return ResponseEntity.ok(Map.of("code", 0, "msg", "权限校验通过"));
|
||||
} else {
|
||||
LOGGER.warn("[权限校验] 拒绝访问: userId={}, uri={}, 无匹配规则", userId, requestUri);
|
||||
return ResponseEntity.status(403).body(Map.of("code", 403, "msg", "无访问权限"));
|
||||
}
|
||||
}
|
||||
|
||||
@GetMapping("/username")
|
||||
public ResponseEntity<?> getUsernameByToken(
|
||||
@CookieValue(value = ConstantConfig.COOKIE_KEY, required = false) String cookieToken,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user