Spring Boot 整合 Spring Security 实现精细化权限控制的关键在于分层设计:先保障认证可靠,再通过角色+权限两级结构支撑细粒度决策,最后落到接口或方法上精准拦截;数据库需5–7张表联动建模,SecurityFilterChain分层放行,方法级用@PreAuthorize结合SpEL表达式控制,UserDetailsService须一次性加载用户、角色、权限并经PasswordEncoder校验。

Spring Boot 整合 Spring Security 实现精细化权限控制,关键不在堆功能,而在分层设计:先保障认证可靠,再通过角色+权限两级结构支撑细粒度决策,最后落到接口或方法上精准拦截。核心是把“谁有权限做某事”这个业务逻辑,翻译成 Spring Security 可执行的安全规则。
数据库建模要支持权限解耦
不能只靠单张用户表硬编码角色。推荐 5–7 张表联动,形成可扩展结构:
- 用户表(sys_user):存账号、BCrypt 加密后的密码、状态
- 角色表(sys_role):role_key 字段用规范命名,如 ROLE_ADMIN、ROLE_EDITOR,不依赖中文名
- 权限表(sys_permission):定义操作级标识,如 sys:user:add、order:pay:cancel,建议按“模块:资源:动作”三级命名
- 关联表(sys_user_role、sys_role_permission):必须用中间表实现多对多,避免字段冗余或权限僵化
这样设计后,一个编辑角色可动态绑定「文章发布」「草稿删除」权限,而不必改代码或重启服务。
SecurityFilterChain 配置要分层放行
不要一股脑把所有路径都写进 .requestMatchers()。按访问性质分三类处理:
立即学习“Java免费学习笔记(深入)”;
-
完全放行:登录接口(
/auth/login)、验证码、静态资源、Swagger 文档(开发环境) -
认证即可:用户中心页、个人设置等,用
.authenticated() -
权限驱动:管理类接口,如
/api/v1/users/**,统一加.authorizeHttpRequests()并配合注解或表达式控制
示例片段:
http.authorizeHttpRequests(authz -> authz
.requestMatchers("/auth/**", "/css/**", "/js/**").permitAll()
.requestMatchers("/api/v1/profile/**").authenticated()
.requestMatchers("/api/v1/admin/**").hasAuthority("sys:admin:full")
.anyRequest().authenticated()
);
方法级控制用 @PreAuthorize + 表达式
URL 级拦截只能到路径,真正精细化靠方法注解。结合 SpEL 表达式可读性强、复用度高:
-
@PreAuthorize("hasAuthority('sys:user:list')"):最常用,匹配权限标识 -
@PreAuthorize("hasRole('ADMIN')"):注意 Role 前会自动加 ROLE_ 前缀,实际比对的是 ROLE_ADMIN -
@PreAuthorize("@permissionService.hasPermission(authentication, 'sys:order:export')"):调用自定义 Service 做运行时判断,适合含数据级权限的场景(如仅能导出自己门店订单)
搭配 @EnableMethodSecurity 开启方法安全,比旧版 @EnableGlobalMethodSecurity 更轻量、更符合 Spring Boot 3.x 规范。
用户权限加载要一次查全
别让每次请求都查 4 张表。实现 UserDetailsService 时,在 loadUserByUsername 中一次性查出用户、角色、权限集合,并构造成 UserDetails 返回:
- 密码字段必须用
PasswordEncoder(推荐BCryptPasswordEncoder)校验,不可明文比对 - 权限列表传入
new User(..., authorities)构造器,Spring Security 会自动注入上下文 - 若权限来自 Redis 缓存,注意缓存失效策略,避免权限变更后延迟生效
这样后续所有 hasAuthority 判断都走内存,无额外 DB 查询压力。


















