diff --git a/src/main/java/com/youlai/boot/common/constant/SecurityConstants.java b/src/main/java/com/youlai/boot/common/constant/SecurityConstants.java
index 5115cce4..a85b1dcb 100644
--- a/src/main/java/com/youlai/boot/common/constant/SecurityConstants.java
+++ b/src/main/java/com/youlai/boot/common/constant/SecurityConstants.java
@@ -39,4 +39,9 @@ public interface SecurityConstants {
* 微信登录路径
*/
String WECHAT_LOGIN_PATH = "/api/v1/auth/wechat-login";
+
+ /**
+ * 角色前缀 Spring Security 的 authorities 角色前缀,用于区分角色和权限
+ */
+ String ROLE_PREFIX = "ROLE_";
}
diff --git a/src/main/java/com/youlai/boot/core/security/model/SysUserDetails.java b/src/main/java/com/youlai/boot/core/security/model/SysUserDetails.java
index 633dbb0d..6005214f 100644
--- a/src/main/java/com/youlai/boot/core/security/model/SysUserDetails.java
+++ b/src/main/java/com/youlai/boot/core/security/model/SysUserDetails.java
@@ -2,9 +2,9 @@ package com.youlai.boot.core.security.model;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
+import com.youlai.boot.common.constant.SecurityConstants;
import com.youlai.boot.system.model.dto.UserAuthInfo;
import lombok.Data;
-import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
@@ -12,51 +12,76 @@ import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
import java.util.Collections;
-import java.util.Set;
import java.util.stream.Collectors;
/**
- * Spring Security 用户对象
+ * Spring Security 用户认证对象
+ *
+ * 封装了用户的基本信息和权限信息,供 Spring Security 进行用户认证与授权。
+ * 实现了 {@link UserDetails} 接口,提供用户的核心信息。
*
- * @author haoxr
- * @since 3.0.0
+ * @author Ray.Hao
+ * @version 3.0.0
*/
@Data
@NoArgsConstructor
public class SysUserDetails implements UserDetails {
- @Getter
+ /**
+ * 用户ID
+ */
private Long userId;
+ /**
+ * 用户名
+ */
private String username;
+ /**
+ * 密码
+ */
private String password;
+ /**
+ * 账号是否启用(true:启用,false:禁用)
+ */
private Boolean enabled;
- private Collection authorities;
-
+ /**
+ * 部门ID
+ */
private Long deptId;
+ /**
+ * 数据权限范围
+ */
private Integer dataScope;
+ /**
+ * 用户角色权限集合
+ */
+ private Collection authorities;
+
+ /**
+ * 构造函数:根据用户认证信息初始化用户详情对象
+ *
+ * @param user 用户认证信息对象 {@link UserAuthInfo}
+ */
public SysUserDetails(UserAuthInfo user) {
this.userId = user.getUserId();
- Set roles = user.getRoles();
- Set authorities;
- if (CollectionUtil.isNotEmpty(roles)) {
- authorities = roles.stream()
- .map(role -> new SimpleGrantedAuthority("ROLE_" + role)) // 标识角色
- .collect(Collectors.toSet());
- } else {
- authorities = Collections.emptySet();
- }
- this.authorities = authorities;
this.username = user.getUsername();
this.password = user.getPassword();
this.enabled = ObjectUtil.equal(user.getStatus(), 1);
this.deptId = user.getDeptId();
this.dataScope = user.getDataScope();
+
+ // 初始化角色权限集合
+ this.authorities = CollectionUtil.isNotEmpty(user.getRoles())
+ ? user.getRoles().stream()
+ // 角色名加上前缀 "ROLE_",用于区分角色 (ROLE_ADMIN) 和权限 (user:add)
+ .map(role -> new SimpleGrantedAuthority(SecurityConstants.ROLE_PREFIX + role))
+ .collect(Collectors.toSet())
+ : Collections.emptySet();
}
diff --git a/src/main/java/com/youlai/boot/core/security/util/SecurityUtils.java b/src/main/java/com/youlai/boot/core/security/util/SecurityUtils.java
index 4344ea49..12e41e18 100644
--- a/src/main/java/com/youlai/boot/core/security/util/SecurityUtils.java
+++ b/src/main/java/com/youlai/boot/core/security/util/SecurityUtils.java
@@ -2,6 +2,7 @@ package com.youlai.boot.core.security.util;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
+import com.youlai.boot.common.constant.SecurityConstants;
import com.youlai.boot.common.constant.SystemConstants;
import com.youlai.boot.core.security.model.SysUserDetails;
import jakarta.servlet.http.HttpServletRequest;
@@ -83,21 +84,21 @@ public class SecurityUtils {
/**
- * 获取用户角色集合
+ * 获取角色集合
*
* @return 角色集合
*/
public static Set getRoles() {
- Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
- if (authentication != null) {
- Collection extends GrantedAuthority> authorities = authentication.getAuthorities();
- if (CollectionUtil.isNotEmpty(authorities)) {
- return authorities.stream().filter(item -> item.getAuthority().startsWith("ROLE_"))
- .map(item -> StrUtil.removePrefix(item.getAuthority(), "ROLE_"))
- .collect(Collectors.toSet());
- }
- }
- return Collections.EMPTY_SET;
+ return Optional.ofNullable(SecurityContextHolder.getContext().getAuthentication())
+ .map(Authentication::getAuthorities)
+ .filter(CollectionUtil::isNotEmpty)
+ .stream()
+ .flatMap(Collection::stream)
+ .map(GrantedAuthority::getAuthority)
+ // 筛选角色,authorities 中的角色都是以 ROLE_ 开头
+ .filter(authority -> authority.startsWith(SecurityConstants.ROLE_PREFIX))
+ .map(authority -> StrUtil.removePrefix(authority, SecurityConstants.ROLE_PREFIX))
+ .collect(Collectors.toSet());
}
/**