Java权限控制实现与项目解析
SpringSecurity基础权限校验最省事:用http.authorizeHttpRequests()配置路径权限,@PreAuthorize控制方法级权限,统一用Permission枚举管理权限标识,JWT场景需将权限写入tokenpayload并自定义JwtAuthenticationConverter。
Spring Security 基础权限校验最省事:用 http.authorizeHttpRequests() 配置路径权限,@PreAuthorize 控制方法级权限,统一用 Permission 枚举管理权限标识,JWT 场景需将权限写入 token payload 并自定义 JwtAuthenticationConverter。

用 Spring Security 做基础权限校验最省事
直接上手 Spring Security 是 Java Web 项目里最稳妥的选择,它不强制你写一堆 if-else 判断角色,而是把权限逻辑下沉到配置和注解层。如果你只是想控制“管理员能删、普通用户只能查”,没必要自己造 PermissionService 轮子。
关键点在于:别手动在 Controller 里调 getUserRoles() 再做字符串匹配,那是反模式。
- 启用
@EnableWebSecurity和@Configuration类 - 用
http.authorizeHttpRequests()配置路径级权限,比如requestMatchers("/api/users/delete").hasRole("ADMIN") - 方法级用
@PreAuthorize("hasRole('ADMIN')")或@PreAuthorize("hasAuthority('user:delete')"),注意hasRole()会自动补前缀ROLE_,而hasAuthority()不会 - 确保你的
UserDetails实现类的getAuthorities()返回的是带正确前缀的GrantedAuthority对象,不是纯字符串列表
自定义权限表达式需继承 DefaultWebSecurityExpressionHandler
Spring Security 默认不支持像 @PreAuthorize("@permissionService.hasPermission(authentication, 'order:refund')") 这种调用自定义服务的写法,除非你显式替换表达式处理器。
否则你会看到 SpelEvaluationException: EL1008E: Property or field 'permissionService' cannot be found。
- 新建配置类,
@Bean注册一个DefaultWebSecurityExpressionHandler实例 - 调用
setPermissionEvaluator()绑定你自己的PermissionEvaluator实现 - 在
PermissionEvaluator的hasPermission()方法里,可安全注入Authentication、目标对象、权限标识符,做数据库查询或缓存判断 - 记得在
@EnableGlobalMethodSecurity中开启prePostEnabled = true(Spring Boot 2.7+ 改为@EnableMethodSecurity)
RBAC 模型下避免硬编码权限字符串
把 "user:read"、"order:write" 散落在代码各处,后期改权限名或加新资源时极易漏改。应该收口成常量或枚举。
更糟的是有人用数字码(如 101 表示用户查看),完全丧失可读性。
- 建一个
Permission枚举,每个值含code(如USER_READ)、value(如"user:read")、desc - Controller 方法上写
@PreAuthorize("hasAuthority(T(com.example.auth.Permission).USER_READ.value)") - 前端菜单/按钮权限也从同一枚举取
value,保持前后端权限标识一致 - 数据库表
sys_permission的code字段建议与枚举名对齐,方便运维查表
@PreAuthorize("hasAuthority(T(com.example.auth.Permission).ORDER_REFUND.value)")
public ResponseEntity refundOrder(@PathVariable Long orderId) {
// ...
}
无状态 JWT 场景下权限信息必须塞进 token payload
如果用了 JWT 且不做 session + Redis 存权限,又没把角色或权限列表放进 token,每次请求都得查库——那跟没用 JWT 没区别,还多了签名开销。
常见错误是只存了 userId,然后在拦截器里再查 DB 加载权限,这既破坏无状态,又拖慢响应。
- 登录成功后,从 DB 查出该用户的全部
GrantedAuthority(即权限字符串),放入 JWT 的authorities自定义 claim - 写一个
JwtAuthenticationConverter,重写convert()方法,从authoritiesclaim 提取并转成SimpleGrantedAuthority列表 - 确保 token 大小可控:权限粒度别太细(比如不用
user:read:123这种带 ID 的),否则 token 膨胀快 - 权限变更后旧 token 不失效,这是 JWT 的固有限制,需要配合短期 token(如 30 分钟)+ refresh token 机制缓解
Postman是一套面向API全生命周期的开发与测试平台,可在Mac上发送和调试多种协议请求,管理集合、环境及认证信息,并完成脚本测试、模拟服务、监控、文档发布和团队协作。它适合开发、测试及运维人员使用,提供个人免费方案。
Docker Desktop 是 Docker 官方为 Mac 提供的容器开发环境,集成 Docker Engine、命令行工具、Compose、Build、Kubernetes 与图形化管理界面。
Android Studio 是 Google 面向安卓应用开发提供的官方集成开发环境,基于 IntelliJ IDEA 构建。它整合智能代码编辑、Gradle 构建、界面预览、设备模拟、性能分析、调试测试及 APK 分析等工具。
PixPix 是面向品牌、卖家和内容团队的在线 AI 图片视频创作平台,提供图视频 Agent、无限画布、图片生成、视频生成、自然语言编辑及商品套图、产品精修和带货视频等电商工具。
Postman 是面向 API 全生命周期的开发与协作平台。Windows 桌面版可用于构建和发送 HTTP、GraphQL、gRPC、WebSocket、MQTT 等请求,并提供环境变量、集合、脚本测试、模拟服务、监控、文档及团队工作区等
Docker Desktop 为 Windows 开发者提供集成式容器环境,内置 Docker Engine、命令行工具、Compose、Build 与 Kubernetes 等组件,可在本机完成镜像构建、容器运行、日志查看和资源管理。













