Java 权限架构知识体系(完整、可落地、企业级)
这是企业级 Java 项目通用的权限架构完整知识体系,从基础概念 → 认证授权 → 权限模型 → 框架选型 → 分布式权限 → 安全最佳实践,覆盖所有核心知识点,可直接用于学习、面试、架构设计。
一、权限基础核心概念
1. 认证(Authentication)—— 身份校验核心
核心定义:解决「你是谁」的问题,是整个权限体系的第一道关卡。 认证是校验访问者身份真实性的过程,所有未通过认证的请求,一律拒绝授权,是授权、鉴权、数据隔离的前置基础。
核心定位:前置拦截、身份确权、会话生成
-
核心作用:区分匿名用户、登录用户、合法用户、非法用户,杜绝非法身份访问系统资源
-
企业主流认证方式(分级落地)基础账号认证:用户名+密码,后台管理系统通用,密码采用 BCrypt 加密存储,禁止明文、MD5、SHA1
-
验证码辅助认证:图形验证码、滑块验证码,防止暴力破解、脚本刷登录
-
动态口令认证:短信验证码、邮箱验证码、TOTP 动态令牌,适用于移动端、高危操作二次认证
-
生物认证:人脸识别、指纹识别,多用于移动端 App、企业内网设备登录
-
企业统一认证:LDAP/AD 域账号、钉钉/企业微信 OAuth2 授权、OIDC 单点登录,适配集团企业统一身份体系
-
第三方开放认证:OAuth2.0、JWT、CAS 单点登录,用于跨系统、跨平台免密登录
-
认证核心三要素身份标识:用户名、用户ID、唯一账号
-
身份凭证:密码、验证码、令牌、签名
-
校验规则:过期时间、设备绑定、IP 限制、登录状态
-
认证结果:认证成功生成有效会话令牌(Token),认证失败返回身份异常,拦截后续所有请求
1.1 认证两大主流实现模式(企业必知)
(1)有状态认证(Session 模式)
-
原理:服务端存储 Session 会话,客户端仅携带 SessionId
-
优点:可控性强、支持主动失效、适配传统单体项目
-
缺点:不支持分布式、前后端分离跨域适配差、集群部署需共享 Session
-
适用场景:传统单体 Web 项目、内网小型系统
(2)无状态认证(Token 模式,企业主流)
-
原理:服务端不存储会话信息,令牌自带用户身份数据,配合 Redis 实现可控会话
-
主流方案:UUID Token+Redis(Sa-Token 首选)、JWT
-
优点:分布式友好、跨域适配、微服务无缝传递、性能更高
-
缺点:纯 JWT 无法主动作废,需搭配 Redis 黑名单实现踢下线、过期管控
-
适用场景:前后端分离、微服务、SaaS 多租户、分布式集群项目
1.2 标准登录认证完整流程(生产级)
-
客户端提交账号密码/验证码等身份凭证
-
服务端校验账号状态(是否禁用、是否删除)
-
密码加密比对(BCrypt 匹配校验)
-
校验通过,加载用户基础信息、租户信息、部门信息
-
生成唯一登录 Token,存入 Redis(设置过期时间、绑定设备)
-
缓存用户角色、权限数据,避免重复查库
-
返回 Token、用户信息、权限标识给前端
-
记录登录日志,完成认证闭环
1.3 高级认证能力(等保合规必备)
-
二次认证:敏感操作(改密、删数据、导出数据)触发二次验证码校验
-
登录限制:单用户单点登录、多端互踢、IP 白名单、设备绑定
-
风险拦截:密码错误次数锁定、异地登录提醒、非法 Token 拦截
-
会话管控:手动踢下线、批量注销、Token 刷新、过期自动登出
1.4 面试高频考点
-
认证和授权的核心区别:认证辨身份,授权定权限,认证在前、授权在后
-
为什么不用 MD5 存密码:不可逆加密易破解,BCrypt 自带盐值、动态算力,安全性更高
-
JWT 优缺点及解决方案:无状态无法主动作废 → 搭配 Redis 黑名单实现会话管控
-
分布式认证核心:统一 Token 规范、Redis 统一存储会话、网关统一校验
2. 授权(Authorization)—— 资源管控核心
核心定义:解决「你能做什么、你能看什么」的问题,是认证通过后的第二道安全关卡。
授权是系统对已认证合法用户,进行资源访问权限校验、操作行为管控、数据范围隔离的过程。认证保证身份合法,授权保证行为合规,无授权校验 = 系统完全裸奔。
核心定位:资源拦截、权限判定、越权防护、数据隔离
核心前提:必须完成认证(登录成功、Token有效),匿名用户无任何授权资格
核心目标:精细化管控用户操作权限,杜绝垂直越权、水平越权,保障系统资源与数据安全
核心本质:基于「用户-角色-权限-数据」的绑定关系,动态判定访问合法性
2.1 授权与认证的核心区别(面试必背)
-
认证(Authentication):校验身份真伪,结果只有「登录成功/失败」,全局统一规则
-
授权(Authorization):校验操作权限,结果因人而异,不同用户权限范围完全不同
-
执行顺序:先认证、后授权,认证失败直接拦截,无需进入授权逻辑
2.2 企业五级授权体系(完整落地)
企业级权限系统,授权分为五个粒度,由浅入深、层层管控,覆盖所有业务场景:
1. 登录授权(基础):校验用户是否登录,拦截所有匿名访问,对应注解 @SaCheckLogin
2. 角色授权:校验用户是否拥有指定角色(如 admin、manager),对应注解 @SaCheckRole("admin")
3. 功能权限授权(接口/按钮/菜单):校验用户是否拥有指定权限码(sys:user:list),对应注解 @SaCheckPermission
4. 数据权限授权:校验用户可操作的数据范围(本人/本部门/全部数据),AOP+MyBatis 拦截自动管控
5. 字段权限授权:校验用户可查看的字段,控制字段显隐、数据脱敏(金融/政务系统必备)
2.3 授权两大核心分类(解决两种越权)
(1)功能授权 —— 防垂直越权
定义:控制用户「能不能操作某个功能、访问某个接口」
场景:普通用户无法访问管理员接口、无法新增/删除数据
实现方式:注解鉴权、拦截器路径匹配、前端按钮隐藏
(2)数据授权 —— 防水平越权
定义:控制用户「能看到哪些数据」,同一接口、不同用户查询结果不同
场景:员工只能看自己数据、部门经理看部门数据、超级管理员看全部数据
实现方式:AOP 切面标记 + ThreadLocal 传递参数 + MyBatis 自动拼接 SQL 过滤条件
2.4 标准授权执行流程(生产级)
-
客户端携带有效 Token 发起业务请求
-
拦截器校验 Token 有效性,完成身份认证
-
从 Redis 缓存中读取当前用户的角色列表、权限码列表、数据范围
-
触发接口授权校验(角色/权限码匹配)
-
触发数据权限切面,拼接数据过滤 SQL
-
触发字段权限拦截,完成字段显隐、脱敏处理
-
校验全部通过,执行业务逻辑;任意环节失败,抛出 403 无权限异常
2.5 授权实现三种主流方式(企业分级使用)
(1)硬编码授权(废弃,不推荐)
-
直接在代码中写 if 判断角色、判断权限
-
缺点:代码冗余、无法动态配置、改权限需要重启服务
(2)注解式授权(主流、标准)
-
基于 Sa-Token/Spring Security 注解,声明式鉴权
-
优点:代码优雅、粒度精准、可复用、易维护
-
常用注解:
@SaCheckLogin、@SaCheckRole、@SaCheckPermission
(3)动态 AOP 授权(高级、数据/字段权限专用)
-
自定义注解 + AOP 切面,无侵入实现权限控制
-
无需修改业务代码,统一拦截、统一管控
-
适用于数据范围过滤、字段脱敏、批量权限管控
2.6 授权缓存机制(性能核心)
-
问题:每次请求查询数据库权限数据,高并发场景性能极差
-
解决方案:用户登录成功后,将角色、权限、数据范围缓存至 Redis
-
缓存策略:权限变更(新增/修改/删除角色、权限)自动清空缓存,实现权限实时刷新
-
优势:大幅减少 DB 查询压力,接口响应速度提升 10 倍以上
2.7 授权安全规则(生产强制约束)
-
最小权限原则:默认禁止所有权限,只开放用户所需最小权限
-
权限互斥原则:关键角色(超级管理员、普通用户)禁止同时赋予同一用户
-
权限不可越级:下级角色无法分配上级角色权限,防止权限泛滥
-
前后端双重校验:前端控制展示,后端强制鉴权,后端校验不可省略
2.8 面试高频考点
-
授权的核心作用:解决垂直越权、水平越权,实现资源精细化管控
-
功能权限和数据权限的区别与落地场景
-
为什么权限必须缓存、缓存如何刷新
-
为什么不能只靠前端做权限:前端可篡改、绕过,后端鉴权是唯一安全底线
-
五级授权体系的执行顺序与优先级
3. 权限三要素(权限体系底层基石)
核心概念:所有权限控制逻辑,归根结底都由「主体、资源、操作」三要素组成。
任何权限判断公式:谁(主体) + 对什么资源(资源) + 做什么操作(操作) = 是否允许。
三要素是 ACL、RBAC、ABAC、数据权限、字段权限的统一底层模型,所有复杂权限逻辑都是对三要素的扩展与组合。
3.1 主体(Subject)—— 谁要访问定义:
发起访问、需要被鉴权的访问者,是权限的「作用对象」。
企业落地分类:
-
个人用户:后台管理员、普通员工、前台用户(最常用)
-
角色主体:以角色为单位批量授权(RBAC 核心)
-
第三方客户端:OAuth 应用、API 调用方、外部系统
-
租户主体:SaaS 系统中以租户为隔离主体
核心特征:主体携带身份信息(用户ID、角色、租户、部门),权限系统根据主体身份判定权限范围。
3.2 资源(Resource)—— 要访问什么定义:
系统中所有需要被保护、不允许匿名随意访问的一切对象,是权限的「保护目标」。
企业全维度资源分类(全覆盖):
-
页面资源:前端菜单、页面路由
-
操作资源:页面按钮、下拉权限、功能入口
-
接口资源:所有后端 API 接口(GET/POST/PUT/DELETE)
-
数据资源:用户数据、部门数据、业务单据、文件记录
-
字段资源:表格列、详情字段、敏感字段(手机号/身份证/金额)
-
文件资源:附件、导出文件、模板文件
核心落地规则:系统所有资源必须统一登记、统一编码(权限码),未登记资源默认禁止访问。
3.3 操作(Action)—— 要做什么行为定义:
主体对资源执行的具体行为动作,是权限管控的「行为维度」。
企业通用操作枚举:
-
基础操作:查询(list)、新增(add)、修改(edit)、删除(delete)
-
业务操作:导入、导出、审核、驳回、提交、撤回、重置
-
系统操作:分配权限、分配角色、改密、清空数据、批量操作
-
特殊操作:查看敏感字段、下载文件、批量导出
3.4 三要素完整权限公式(企业通用)
权限放行条件 = 主体拥有该资源的对应操作权限
示例拆解:
-
主体:普通员工
-
资源:用户列表接口
-
操作:查询
-
判定:员工无
sys:user:list权限 → 禁止访问
3.5 三要素与五级授权体系对应关系
-
登录授权、角色授权 → 校验主体合法性
-
功能权限(菜单/按钮/接口)→ 校验资源+操作
-
数据权限 → 精细化约束资源范围
-
字段权限 → 精细化约束资源粒度
3.6 三要素落地核心规范
-
主体唯一标识:以 userId、roleId、tenantId 作为身份唯一判定依据
-
资源统一编码:严格遵循
模块:资源:操作权限码规范 -
操作最小粒度:增删改查分离,禁止一个权限控制多个操作
-
默认拒绝原则:未配置权限的「主体-资源-操作」组合,一律拦截禁止访问
3.7 面试高频考点
-
权限三要素分别是什么?各自作用是什么?
-
为什么所有权限都可以归结为三要素组合?
-
功能权限、数据权限分别管控三要素的哪一部分?
-
三要素如何支撑 RBAC、ABAC 权限模型?
4. 垂直权限 vs 水平权限(解决所有越权问题)
核心总述:企业系统所有权限安全漏洞,归根结底只有两种:垂直越权、水平越权。 垂直权限管控「功能访问」,水平权限管控「数据访问」,二者结合构成系统完整越权防护体系,是生产安全、等保考核、面试高频核心。
4.1 垂直权限(功能权限)
全称:垂直访问控制 / 功能权限
核心定义:控制用户能不能访问某个功能、某个接口、某个菜单。
管控维度:功能层级、接口层级、菜单层级。
通俗理解:不同角色的「功能层级差异」。 普通员工没有管理员功能入口,无法调用管理员接口,属于上下级权限隔离。
对应越权漏洞:垂直越权
漏洞场景:低权限用户,手动请求高权限接口,实现越级操作。
-
普通用户手动调用「新增用户、删除用户、分配权限」管理员接口
-
游客绕过前端菜单,直接通过 URL 访问后台管理页面
-
前端隐藏按钮,后端未做鉴权,导致接口裸奔
解决方案(企业标准)
-
基于权限码注解鉴权:
@SaCheckPermission("sys:user:add") -
基于角色鉴权:
@SaCheckRole("admin") -
拦截器统一拦截未授权接口资源
-
严格遵循「后端强制鉴权,前端仅做展示」
落地特点
-
控制范围:全局功能、接口、菜单、按钮
-
判定依据:角色、权限码
-
结果:有权全量功能可用,无权直接拦截接口
-
依赖模型:标准 RBAC
4.2 水平权限(数据权限)
全称:水平访问控制 / 数据权限
核心定义:同一角色、同一接口、同一功能,控制用户「能看到哪些数据、能操作哪些数据」。 管控维度:数据范围、数据行级别。
通俗理解:同级角色的「数据隔离差异」。 大家都是普通员工、权限一样,但只能看自己的数据,不能看别人的数据。
对应越权漏洞:水平越权(线上高发高危漏洞)
漏洞场景:
- 同级别用户,篡改参数查看/操作他人数据。
-
用户A修改URL参数,查看用户B的订单、工资、合同数据
-
员工通过ID遍历,爬取全公司所有业务数据
-
部门员工查看其他部门私密业务单据
解决方案(企业标准)
-
自定义
@DataScope注解标记数据权限接口 -
AOP 切面根据当前登录用户身份动态计算数据范围
-
MyBatis 拦截器自动拼接 SQL 过滤条件(无需手动改代码)
-
线程上下文 ThreadLocal 传递数据权限参数,全局生效
落地特点
-
控制范围:数据库行级数据
-
判定依据:用户ID、部门ID、数据范围枚举
-
结果:同一接口,不同用户查询结果不同
-
依赖模型:RBAC + 数据范围扩展
4.3 五大数据权限范围(企业统一标准)
水平权限(数据权限)共分为 5 个等级,覆盖 100% 业务场景:
1. 全部数据:超级管理员,查看系统所有数据
2. 本部门及子部门数据:部门总监,管辖全部下属数据
3. 本部门数据:部门经理,仅查看本级部门数据
4. 仅本人数据:普通员工,只能操作自己创建的数据
5. 自定义数据:指定可访问部门,适配复杂组织架构
4.4 垂直权限 & 水平权限 核心对比表(面试必背)
|
对比维度 |
垂直权限(功能权限) |
水平权限(数据权限) |
|---|---|---|
|
解决问题 |
能不能用这个功能/接口 |
能用功能,但能看哪些数据 |
|
对抗漏洞 |
垂直越权(越级操作) |
水平越权(越数据操作) |
|
控制粒度 |
菜单、按钮、接口、功能 |
数据库行级数据 |
|
判定依据 |
角色、权限码 |
用户ID、部门ID、数据范围 |
|
实现方式 |
注解鉴权、拦截器路径校验 |
AOP+MyBatis 动态 SQL 过滤 |
|
适用场景 |
上下级权限隔离 |
同级数据隔离 |
4.5 生产级完整防护逻辑(双权限闭环)
一次请求 = 先防垂直越权,再防水平越权,双重校验杜绝所有越权风险。
-
拦截器校验 Token,完成认证
-
垂直权限校验:判断用户是否拥有当前接口权限,无权限直接拦截
-
水平权限校验:根据用户身份拼接数据过滤 SQL
-
查询数据、脱敏字段、返回结果
4.6 面试高频考点(终极总结)
-
什么是垂直越权? 低权限用户访问高权限功能/接口,属于功能层级越权。
-
什么是水平越权? 同级用户互相访问私有数据,属于数据层级越权,是线上最常见高危漏洞。
-
为什么必须双权限同时存在? 只做功能权限防不住数据泄露,只做数据权限防不住越级操作。
-
水平权限核心难点? 无侵入动态 SQL 拼接、多场景数据范围适配、权限缓存刷新。
-
前端隐藏按钮安全吗? 不安全,只能防普通用户,无法防接口遍历,后端双重校验是唯一底线。
二、主流权限模型(必掌握)
企业 90% 系统都基于这 4 种模型组合使用。
1. ACL 访问控制列表(原始权限模型)
全称:Access Control List,访问控制列表
核心定位:业界最原始、最简单的权限模型,是所有权限模型的鼻祖。
核心设计思想:用户直接绑定权限,无中间角色层,一对一直接授权。
1.1 ACL 核心结构
权限链路:用户 User → 直接关联权限 Permission
每一条权限记录,都代表「某个用户 拥有 某个资源的操作权限」,权限粒度直接绑定到个人。
1.2 底层表结构(极简)
-
用户表 sys_user:存储用户基础信息
-
权限表 sys_permission:存储系统所有资源权限(菜单、接口、按钮)
-
用户权限关联表 sys_user_perm:直接绑定用户与权限,无角色中间表
对比 RBAC:ACL 没有角色表、角色权限表、用户角色表,结构极度精简。
1.3 执行流程
-
用户登录系统
-
系统根据 userId 查询「用户-权限关联表」
-
加载当前用户的全部权限集合
-
请求接口时,直接匹配用户所持权限码,完成鉴权
1.4 适用业务场景
-
小型单体系统、简易后台、内部小工具
-
用户数量少、权限差异化极低的系统
-
无需批量授权、几乎不调整权限的静态系统
-
嵌入式系统、简单管理平台
1.5 核心优点
-
结构极简:表结构少、代码逻辑简单、上手成本极低
-
鉴权速度快:少了角色层关联,直接查询用户权限,链路更短
-
灵活独立:可以给单个用户单独配置专属权限,无角色捆绑限制
1.6 致命缺点(企业淘汰核心原因)
-
无法批量授权:无角色中间层,只能逐个给用户授权,100 个用户需要操作 100 次
-
维护成本爆炸:权限变更需要逐个修改所有用户,极易出现权限不一致、遗漏配置
-
权限冗余严重:大量用户权限重复,数据冗余、难以统一管理
-
无层级管控:不支持角色继承、权限互斥、层级隔离,无法适配复杂组织架构
-
扩展性极差:无法扩展数据权限、批量权限、租户权限,不支持中大型项目
1.7 ACL 与 RBAC 核心区别(面试高频)
-
ACL:用户 → 权限,扁平直连,适合小型系统
-
RBAC:用户 → 角色 → 权限,分层解耦,适合企业级系统
-
核心升级点:RBAC 通过「角色中间层」解决了 ACL 无法批量授权的痛点
1.8 面试总结考点
-
ACL 是什么?用户直接绑定权限,无角色中间层
-
为什么企业项目不用 ACL?用户量大维护成本极高,无法批量授权
-
ACL 和 RBAC 的最大差异?是否存在角色中间层,实现权限批量复用
-
ACL 适用场景?小型静态系统、用户量少、权限固定的项目
2. RBAC 角色基础访问控制(企业最主流、行业标准)
全称:Role-Based Access Control,基于角色的访问控制
核心定位:目前95%以上企业后台系统、SaaS系统、微服务项目的通用标准权限模型,完美解决ACL模型无法批量授权、维护成本高的致命痛点,是权限体系的核心基石模型。
核心设计思想:用户 → 角色 → 权限,引入「角色」中间层,实现用户与权限解耦,批量复用权限配置。
核心公式:用户拥有角色,角色绑定权限 = 用户拥有对应权限
2.1 RBAC 四大分层版本(面试必背、逐级增强)
RBAC 并非单一模型,分为四个迭代版本,功能逐级叠加,适配不同复杂度的业务系统:
(1)RBAC0(基础标准版|所有企业系统必备)
核心能力:最基础的用户、角色、权限关联关系,无任何额外约束与继承能力。
权限链路:用户 - 角色(多对多)、角色 - 权限(多对多)
核心特性:一个用户可绑定多个角色,一个角色可分配多个用户;一个角色可拥有多个权限,一个权限可被多个角色复用。
适用场景:绝大多数中小型管理系统、常规后台项目,是企业落地最广泛的版本。
(2)RBAC1(角色继承版|中大型企业架构)
核心能力:在RBAC0基础上,新增角色层级继承能力,支持上下级角色权限自动传递。
继承规则:高级角色自动拥有低级角色的所有权限,无需重复配置。例如:部门总监角色 自动继承 部门经理角色的全部权限。
分类:分为单继承(一对一继承)、多继承(一个角色可继承多个下级角色权限)。
适用场景:集团化企业、多层级组织架构、岗位层级分明的系统(国企、政务、大型企业OA)。
(3)RBAC2(角色约束版|高安全合规系统)
核心能力:在RBAC0基础上,新增权限约束、安全管控规则,杜绝权限滥用,满足等保合规要求。
核心约束规则:
-
角色互斥:两个冲突角色不能同时赋予同一用户(如超级管理员和普通员工、审核人和提交人),防止权限冲突、越权违规
-
基数约束:限制核心角色的最大绑定人数(如超级管理员仅允许1-2人),减少高危权限扩散风险
-
先决角色:获取高级角色权限前,必须先拥有基础角色权限,规范权限分配流程
-
时间约束:角色权限可设置有效期,到期自动回收权限,适配临时岗位、外包人员场景
适用场景:金融、政务、医疗、国企等高安全等级、强合规要求系统。
(4)RBAC3(完整增强版|大型复杂系统终极方案)
核心能力:RBAC1 + RBAC2 合集,同时支持角色继承 + 权限约束,是功能最完整、安全性最高的RBAC版本。
核心优势:既满足多层级组织权限复用需求,又能通过约束规则严控权限风险,兼顾灵活性与安全性。
适用场景:大型集团SaaS平台、政务一体化系统、金融核心业务系统。
2.2 RBAC 企业标准五表结构(面试/开发必背)
区别于ACL的三表结构,RBAC通过五表解耦,实现权限批量复用,是企业项目固定表结构设计:
-
1. 用户表 sys_user:存储用户账号、密码、部门、状态等基础信息
-
2. 角色表 sys_role:存储角色标识、角色名称、数据权限范围、排序等
-
3. 权限表 sys_permission:存储菜单、接口、按钮权限,统一权限码(模块:功能:操作)
-
4. 用户角色关联表 sys_user_role:多对多关联,实现一个用户绑定多个角色
-
5. 角色权限关联表 sys_role_permission:多对多关联,实现一个角色绑定多个权限
核心设计亮点:所有权限只需要给角色配置一次,所有绑定该角色的用户自动继承权限,彻底解决ACL重复授权问题。
2.3 RBAC 标准执行流程(生产级)
-
用户登录系统,完成身份认证,生成有效Token
-
根据用户ID查询 sys_user_role,获取用户绑定的所有角色
-
根据角色ID批量查询 sys_role_permission,汇总用户所有权限码
-
将用户角色、权限列表、数据范围缓存至Redis,提升后续鉴权性能
-
用户请求接口时,拦截器/注解校验当前用户是否拥有对应角色或权限码
-
校验通过则放行,校验失败抛出403无权限异常
2.4 RBAC 核心优点(碾压ACL的关键)
-
权限解耦、可批量复用:权限绑定角色,而非绑定用户,一次配置、全员复用,百个用户无需百次操作
-
维护成本极低:岗位相同的用户共用一套角色权限,权限变更仅需修改角色配置,全局生效
-
支持层级拓展:可通过RBAC1实现角色继承,适配企业多层级组织架构
-
安全性可控:可结合RBAC2实现角色互斥、权限时效、人数限制,满足合规要求
-
扩展性极强:可无缝拓展数据权限、字段权限、租户权限,适配微服务、SaaS系统
-
适配所有业务场景:从小型单体到大型分布式系统均可使用,通用性拉满
2.5 RBAC 固有缺点(落地避坑)
-
仅支持静态权限:基于角色、权限码固定配置,无法适配动态、场景化临时权限
-
细粒度权限薄弱:原生RBAC仅管控功能权限(菜单/接口/按钮),不自带数据权限、字段权限,需要手动拓展实现
-
复杂场景适配不足:针对按时间、IP、部门动态变化的权限场景,单纯RBAC无法满足,需结合ABAC模型
2.6 RBAC 与 ACL 终极对比(面试高频)
|
对比维度 |
ACL模型 |
RBAC模型 |
|---|---|---|
|
权限链路 |
用户直接绑定权限(扁平结构) |
用户-角色-权限(分层解耦) |
|
批量授权 |
不支持,逐用户配置 |
支持,角色统一批量授权 |
|
维护成本 |
用户量大时成本极高、易出错 |
极低,统一配置、全局生效 |
|
拓展能力 |
极差,无法适配复杂业务 |
极强,可拓展数据、字段、租户权限 |
|
适用场景 |
小型静态简易系统 |
95%企业级动态业务系统 |
2.7 落地拓展:RBAC 企业增强方案
原生RBAC仅支持功能权限,企业生产中均使用RBAC + 数据权限 + 字段权限增强方案,补齐原生短板:
-
基于RBAC角色体系,拓展数据范围字段(全部/本部门/本人/自定义),实现水平权限管控
-
基于角色权限,拓展字段脱敏/显隐配置,实现字段级精细化权限
-
结合Redis缓存权限、角色数据,解决高并发鉴权性能问题
-
结合AOP切面,实现无侵入式权限校验,不耦合业务代码
2.8 面试高频终极考点
-
RBAC的核心思想是什么?引入角色中间层,实现用户与权限解耦,支持批量授权
-
RBAC四个版本的区别?核心是新增角色继承、权限约束能力
-
为什么企业不用ACL而用RBAC?解决批量授权、维护成本高、无法拓展的核心痛点
-
原生RBAC的短板?无数据权限、无动态权限、仅支持静态功能鉴权
-
如何基于RBAC实现数据权限?拓展数据范围字段+AOP+MyBatis动态SQL拼接
-
多角色权限叠加规则?用户多个角色权限自动合并、取并集,权限范围叠加最大化
核心:用户 → 角色 → 权限
-
RBAC0:基础版(用户 - 角色 - 权限)
-
RBAC1:角色继承(上级自动拥有下级权限)
-
RBAC2:角色约束(互斥角色、数量限制)
-
RBAC3:RBAC1+RBAC2 综合
企业标准表结构(必背)
-
用户表(user)
-
角色表(role)
-
权限表(permission)
-
用户 - 角色关联表(user_role)
-
角色 - 权限关联表(role_permission)
3. ABAC 属性权限控制(灵活高级、动态权限终极方案)
全称:Attribute-Based Access Control,基于属性的访问控制 核心定位:弥补 RBAC 静态权限短板 的高级动态权限模型,是复杂业务、精细化场景、临时权限、条件权限的企业终极解决方案,广泛应用于金融、政务、医疗、大型SaaS系统。 核心设计思想:不依赖固定角色,通过「用户属性、资源属性、环境属性、操作属性」多维条件组合,动态计算权限放行规则,实现条件化、动态化、精细化鉴权。
核心公式:多维度属性条件匹配 = 权限放行/拦截
3.1 ABAC 四大核心属性(企业标准)
ABAC 所有权限规则,均由四大属性自由组合生成,适配任意复杂业务场景:
(1)用户属性(主体属性):
访问者自身属性 基础信息:用户ID、账号、岗位、部门、职级、角色、租户
业务属性:用户等级、岗位类型、审批权限、岗位职责
示例:仅部门总监、仅高级员工、仅本部门人员
(2)资源属性(客体属性):
被访问资源的属性 数据属性:数据创建人、数据所属部门、数据密级、数据类型、数据状态
功能属性:接口级别、菜单类型、操作风险等级
示例:机密数据、本部门业务单据、未审批单据
(3)环境属性(场景属性):
访问时的上下文环境 时空属性:访问时间、工作日/节假日、白天/夜间
网络属性:访问IP、内网/外网、设备终端、地域
安全属性:是否二次认证、是否可信设备、是否异地登录
示例:仅工作时间可操作、内网可访问、外网禁止导出
(4)操作属性(行为属性):
用户执行的操作行为 操作类型:查询、新增、修改、删除、导出、审核、驳回
操作风险:高危操作、普通操作、敏感操作
示例:普通员工可查询、不可导出;管理员可全部操作
3.2 ABAC 核心执行流程(生产级)
-
用户登录认证成功,加载用户全部属性信息(部门、职级、角色等)
-
用户发起业务请求,拦截器捕获当前用户、资源、环境、操作四大属性
-
系统加载预设的ABAC权限规则表达式
-
动态匹配属性条件,校验是否满足放行规则
-
匹配通过则放行,匹配失败直接抛出403无权限异常
-
支持权限规则缓存,提升高并发鉴权性能
3.3 典型落地场景(RBAC 无法实现的场景)
所有带条件、动态变化、临时生效的权限场景,均需ABAC实现:
-
时间动态权限:仅工作日9:00-18:00允许后台操作,夜间禁止高危操作
-
网络环境权限:内网可自由查询数据,外网仅可查看基础数据、禁止导出删除
-
数据密级权限:普通员工仅可查看公开数据,主管可查看内部数据,总监可查看机密数据
-
临时岗位权限:员工临时顶岗一周,自动临时开通对应权限,到期自动回收
-
二次认证权限:外网访问敏感数据必须二次验证码,内网直接放行
-
流程关联权限:单据未审批仅可查看,审批通过后可修改,驳回后不可操作
3.4 ABAC 核心优点(碾压RBAC的核心优势)
-
支持动态条件权限:摆脱固定角色绑定,基于场景动态判定权限,适配复杂多变业务
-
权限粒度极致精细:支持用户、资源、环境、操作多维组合,实现字段级、数据级、场景级精准管控
-
无需频繁改配置:规则配置一次永久生效,无需频繁调整角色、权限关联关系
-
适配临时/时效权限:完美解决临时顶岗、时效授权、场景化授权问题
-
安全等级更高:多维度交叉校验,杜绝单一角色权限泛滥,满足等保三级、金融合规要求
-
扩展性极强:可自由新增属性、新增规则,适配所有极端复杂业务场景
3.5 ABAC 固有缺点(落地避坑)
-
设计复杂、学习成本高:多属性组合规则抽象,相较于RBAC更难理解与落地
-
规则配置繁琐:复杂场景需要编写、调试权限表达式,维护成本高于基础RBAC
-
鉴权性能略低:相较于RBAC简单角色/权限码匹配,多属性校验逻辑更重,需依赖缓存优化
-
小型系统过度设计:普通后台、简单OA系统无需使用,徒增开发成本
3.6 ABAC vs RBAC 核心对比(面试必考)
|
对比维度 |
RBAC(角色权限) |
ABAC(属性权限) |
|---|---|---|
|
核心依据 |
固定角色、固定权限码 |
用户/资源/环境/操作多维动态属性 |
|
权限特性 |
静态权限,配置后固定生效 |
动态权限,随场景、环境、条件实时变化 |
|
适配场景 |
常规固定岗位、静态功能权限 |
复杂条件、临时时效、场景化精细化权限 |
|
粒度精度 |
菜单、接口、数据范围粗粒度 |
字段、数据、场景极致细粒度 |
|
维护成本 |
低,批量角色复用 |
中高,规则表达式维护 |
|
依赖复杂度 |
低,五表结构简单清晰 |
高,需属性管理、规则引擎支撑 |
3.7 企业落地最佳方案(RBAC+ABAC 混合模式)
生产环境不会单独使用ABAC,主流落地组合:
-
基础权限用RBAC:菜单、接口、按钮、岗位固定权限,保证系统基础权限简洁可控
-
复杂动态权限用ABAC:时间、IP、数据密级、临时操作、场景化精细化管控
-
双层校验闭环:先通过RBAC校验基础功能权限,再通过ABAC校验场景动态权限,兼顾简洁性与安全性
3.8 面试高频终极考点
-
ABAC核心思想? 基于用户、资源、环境、操作多维度属性,动态条件化鉴权
-
ABAC和RBAC的核心区别? RBAC是静态角色权限,ABAC是动态属性条件权限
-
什么场景必须用ABAC? 带时间、IP、状态、临时时效等动态条件的权限场景
-
企业为什么采用RBAC+ABAC混合架构? 兼顾基础权限的简洁性和复杂场景的灵活性
-
ABAC四大属性分别是什么? 用户属性、资源属性、环境属性、操作属性
4. PBAC 策略权限控制(网关级、微服务终极方案)
全称:Policy-Based Access Control,基于策略的访问控制
核心定位:面向微服务、网关、云原生、多租户、大型分布式系统的高级权限模型,是四大权限模型中最灵活、最适配集群架构的方案,常作为全局网关鉴权、跨服务统一权限管控的核心实现。 核心设计思想:摒弃固定的角色、权限绑定关系,以自定义策略规则为核心,通过动态表达式、条件语句、权限策略组,灵活定义放行/拦截规则,支持复杂组合条件、优先级、黑白名单管控。
核心公式:请求上下文 + 预设策略表达式匹配 = 权限放行结果
4.1 PBAC 核心核心组成要素
PBAC 所有权限判定,都由标准化策略组件构成,可自由组合、灵活配置:
-
策略主体:用户、角色、租户、客户端IP、服务实例、请求来源
-
策略资源:API接口、路由地址、服务名称、请求方法、文件资源
-
策略条件:时间、IP、租户、角色、数据状态、请求参数、环境属性
-
策略动作:允许放行、拒绝访问、二次认证、限流、日志记录
-
策略优先级:多条规则冲突时,按优先级判定,高优先级规则覆盖低优先级
-
策略生效周期:支持永久生效、定时生效、临时过期、节假日禁用
4.2 PBAC 标准策略表达式(企业实战)
PBAC 核心优势就是支持可视化、可配置、可动态更新的策略表达式,无需改代码重启服务,常用实战规则:
-
基础角色策略:
用户角色包含 admin → 允许所有接口访问 -
IP环境策略:
外网IP + 高危删除接口 → 直接拦截 -
时间时效策略:
非工作时间(18:00-次日9:00) → 禁止数据导出操作 -
租户隔离策略:
租户A用户 → 仅可访问租户A资源 -
组合复杂策略:
角色=部门经理 AND 内网访问 AND 工作日 → 允许审核单据 -
兜底策略:
所有未匹配规则的请求 → 统一拦截拒绝
4.3 PBAC 执行流程(网关级全局鉴权)
-
客户端发起请求,统一进入微服务网关(Gateway)
-
网关完成Token校验、身份解析,获取请求全量上下文参数
-
加载系统预设的所有PBAC权限策略(已缓存、支持动态刷新)
-
逐条匹配策略规则,根据优先级筛选最终生效策略
-
执行策略动作(放行/拦截/二次认证)
-
放行请求转发至后端微服务,拦截则直接返回403权限异常
-
记录策略执行日志,用于权限审计、安全溯源
4.4 PBAC 核心落地场景(独有、不可替代)
PBAC 是网关、云原生、SaaS多租户、跨系统权限专属方案,RBAC/ABAC无法完美替代:
-
微服务网关全局鉴权:统一入口管控所有服务接口,无需每个服务单独鉴权
-
SaaS多租户权限隔离:不同租户配置独立权限策略,实现租户权限完全隔离
-
跨系统统一权限:对接第三方系统、OAuth客户端、外部API调用权限管控
-
动态黑白名单管控:IP黑名单、账号临时封禁、接口临时限流拦截
-
复杂时效权限场景:分时段、分环境、分客户端的差异化权限规则
-
零代码权限变更:线上动态修改权限策略,无需重启服务、无需改代码
4.5 PBAC 核心优点
-
极致灵活、无固化规则:不依赖角色、属性固化结构,任意复杂条件均可通过策略配置实现
-
动态热更新:支持线上修改、新增、删除权限策略,实时生效,无需重启服务
-
全局统一管控:适配网关层统一鉴权,实现所有微服务权限收口,杜绝权限散乱
-
多维度组合适配:融合RBAC角色规则、ABAC属性规则,兼容静态+动态所有场景
-
优先级可控、冲突可解:支持策略优先级配置,完美解决多规则冲突问题
-
适配云原生架构:轻量化、可配置、易扩展,适配容器化、分布式集群部署
4.6 PBAC 固有缺点(落地避坑)
-
规则抽象、学习成本高:策略表达式灵活但抽象,新手难以快速梳理权限逻辑
-
复杂场景易混乱:策略过多时,规则叠加复杂,易出现权限漏洞、逻辑冲突
-
不适合简单系统:单体小型系统使用PBAC属于过度设计,徒增开发维护成本
-
依赖网关层:脱离网关单独使用效果差,更适合分布式架构,单体项目优势不明显
4.7 四大权限模型终极横向对比(面试天花板)
|
权限模型 |
核心原理 |
权限特性 |
适用架构 |
适用场景 |
|---|---|---|---|---|
|
ACL |
用户直接绑定权限 |
静态、扁平、无复用 |
小型单体 |
简易内部工具、静态小系统 |
|
RBAC |
用户-角色-权限分层解耦 |
静态、可批量复用 |
单体/基础微服务 |
95%企业常规后台系统 |
|
ABAC |
多维度属性动态匹配 |
动态、精细化、场景化 |
中大型分布式 |
复杂条件、临时权限、高安全系统 |
|
PBAC |
自定义策略表达式管控 |
全动态、可配置、全局化 |
微服务/云原生/SaaS |
网关统一鉴权、多租户、跨系统权限 |
4.8 企业终极落地组合方案(四大模型融合)
大型分布式项目标准权限架构,各司其职、完美互补:
-
底层基础权限:RBAC:管控岗位、角色、菜单、接口基础静态权限,保证业务权限简洁可控
-
业务精细化权限:ABAC:处理时间、IP、数据状态、临时授权等动态场景权限
-
全局网关权限:PBAC:微服务网关层统一拦截、租户隔离、黑白名单、全局策略管控
-
极简小型系统:保留ACL:轻量化系统简化架构,降低维护成本
4.9 面试高频终极考点
-
PBAC核心思想? 基于自定义策略表达式,动态匹配请求上下文,实现全局灵活鉴权
-
PBAC和ABAC的区别? ABAC基于固定四大属性组合,PBAC是自定义任意策略规则,自由度更高
-
PBAC主要落地位置? 微服务网关层,做全局统一权限收口
-
为什么大型SaaS系统要用PBAC? 支持多租户独立策略、动态热更新、全局权限隔离
-
四大权限模型如何选型? 小系统用ACL、常规企业用RBAC、复杂场景叠加ABAC、分布式网关用PBAC
三、Java 权限核心技术栈
1. 基础权限实现(手写原生代码|无框架依赖)
核心说明:不依赖 Spring Security、Sa-Token 等权限框架,基于SpringBoot 原生拦截器 + 自定义注解 + AOP + Redis 手写一套完整的权限体系,彻底吃透权限底层实现原理,适配面试手撕代码、底层原理问答、简易项目落地。
实现能力全覆盖:登录认证、Token会话管理、接口登录拦截、角色鉴权、权限码鉴权、权限缓存、简易数据权限底层逻辑。
技术依赖:SpringBoot Web、Redis、Lombok、MyBatis(基础业务)
1.1 自定义权限注解(鉴权标识)
通过自定义注解标记接口权限,实现声明式鉴权,区分登录校验、角色校验、权限码校验。
(1)登录校验注解
import java.lang.annotation.*;
/**
* 校验用户是否登录
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckLogin {
}
(2)角色权限校验注解
import java.lang.annotation.*;
/**
* 校验用户角色权限
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckRole {
// 需要的角色标识,多个角色满足其一即可
String[] value() default {};
}
(3)功能权限码校验注解
import java.lang.annotation.*;
/**
* 校验用户权限码
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CheckPermission {
// 需要的权限码,如 sys:user:list
String[] value() default {};
}
1.2 全局常量与工具类
(1)权限常量类
/**
* 权限全局常量
*/
public class PermissionConstant {
// Redis-Token前缀
public static final String TOKEN_PREFIX = "user:token:";
// 用户权限缓存前缀
public static final String USER_PERM_PREFIX = "user:perm:";
// Token过期时间 2小时
public static final long TOKEN_EXPIRE = 2 * 60 * 60;
}
(2)Token生成工具类
import java.util.UUID;
/**
* 手写Token工具类
*/
public class TokenUtil {
/**
* 生成唯一登录Token
*/
public static String generateToken() {
return UUID.randomUUID().toString().replace("-", "");
}
}
(3)用户上下文工具类(线程隔离)
import com.alibaba.fastjson.JSONObject;
import java.util.List;
/**
* 线程上下文:存储当前登录用户信息,全局可获取
*/
public class UserContext {
private static ThreadLocal<JSONObject> USER_INFO = new ThreadLocal<>();
// 设置用户信息
public static void setUser(JSONObject user) {
USER_INFO.set(user);
}
// 获取用户信息
public static JSONObject getUser() {
return USER_INFO.get();
}
// 获取用户ID
public static Long getUserId() {
return getUser().getLong("userId");
}
// 获取用户角色列表
public static List<String> getRoleList() {
return getUser().getJSONArray("roleList").toJavaList(String.class);
}
// 获取用户权限码列表
public static List<String> getPermList() {
return getUser().getJSONArray("permList").toJavaList(String.class);
}
// 清除上下文(防止内存泄漏)
public static void remove() {
USER_INFO.remove();
}
}
1.3 登录认证核心逻辑(手写会话)
实现账号密码校验、Token生成、Redis会话存储、权限缓存,完整登录闭环。
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
@Service
public class LoginService {
@Resource
private StringRedisTemplate stringRedisTemplate;
// 模拟数据库查询用户、角色、权限
public Map<String, Object> login(String username, String password) {
// 1. 校验账号密码(模拟BCrypt加密比对)
if (!"123456".equals(password)) {
throw new RuntimeException("账号或密码错误");
}
// 2. 模拟查询用户信息、角色、权限
Long userId = 1001L;
List<String> roleList = List.of("admin", "manager");
List<String> permList = List.of("sys:user:list", "sys:user:add", "sys:user:edit");
// 3. 生成唯一Token
String token = TokenUtil.generateToken();
// 4. 封装用户会话信息
String userInfo = "{\"userId\":" + userId + ",\"roleList\":" + roleList + ",\"permList\":" + permList + "}";
// 5. Redis存储会话(实现无状态、可失效、可踢下线)
stringRedisTemplate.opsForValue().set(PermissionConstant.TOKEN_PREFIX + token, userInfo,
PermissionConstant.TOKEN_EXPIRE, TimeUnit.SECONDS);
// 缓存用户权限,提升鉴权性能
stringRedisTemplate.opsForValue().set(PermissionConstant.USER_PERM_PREFIX + userId,
userInfo, PermissionConstant.TOKEN_EXPIRE, TimeUnit.SECONDS);
// 6. 返回Token给前端
Map<String, Object> result = new HashMap<>();
result.put("token", token);
result.put("userInfo", userInfo);
return result;
}
// 登出逻辑
public void logout(String token) {
// 删除Redis会话,实现主动踢下线
stringRedisTemplate.delete(PermissionConstant.TOKEN_PREFIX + token);
UserContext.remove();
}
}
1.4 核心拦截器(统一认证拦截)
拦截所有请求,解析Token、校验登录状态、存入用户上下文,是权限校验的前置核心。
import com.alibaba.fastjson.JSONObject;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 非接口请求直接放行
if (!(handler instanceof HandlerMethod)) {
return true;
}
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 1. 获取请求头Token
String token = request.getHeader("Authorization");
if (token != null && token.startsWith("Bearer ")) {
token = token.substring(7);
}
// 2. 判断接口是否需要登录
boolean needLogin = handlerMethod.hasMethodAnnotation(CheckLogin.class);
if (!needLogin) {
return true;
}
// 3. 校验Token是否存在、有效
if (token == null) {
throw new RuntimeException("未登录,请先登录");
}
String userJson = stringRedisTemplate.opsForValue().get(PermissionConstant.TOKEN_PREFIX + token);
if (userJson == null) {
throw new RuntimeException("登录已过期,请重新登录");
}
// 4. 解析用户信息,存入线程上下文
JSONObject userInfo = JSONObject.parseObject(userJson);
UserContext.setUser(userInfo);
return true;
}
// 请求结束清除上下文,防止内存泄漏
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
UserContext.remove();
}
}
1.5 AOP切面授权(角色+权限码鉴权)
基于AOP实现接口级角色、权限码校验,无侵入业务代码,实现垂直权限管控。
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Aspect
@Component
public class PermissionAop {
// 拦截权限码校验注解
@Before("@annotation(checkPermission)")
public void checkPermission(JoinPoint joinPoint, CheckPermission checkPermission) {
// 获取接口所需权限码
String[] needPerms = checkPermission.value();
if (needPerms.length == 0) {
return;
}
// 获取用户拥有的权限码
List<String> userPerms = UserContext.getPermList();
// 校验是否包含所需权限
List<String> needList = Arrays.asList(needPerms);
boolean hasPerm = userPerms.stream().anyMatch(needList::contains);
if (!hasPerm) {
throw new RuntimeException("无该操作权限");
}
}
// 拦截角色校验注解
@Before("@annotation(checkRole)")
public void checkRole(JoinPoint joinPoint, CheckRole checkRole) {
// 获取接口所需角色
String[] needRoles = checkRole.value();
if (needRoles.length == 0) {
return;
}
// 获取用户拥有的角色
List<String> userRoles = UserContext.getRoleList();
List<String> needList = Arrays.asList(needRoles);
boolean hasRole = userRoles.stream().anyMatch(needList::contains);
if (!hasRole) {
throw new RuntimeException("角色权限不足");
}
}
}
1.6 拦截器注册配置
将自定义拦截器注入Spring容器,生效全局请求拦截。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Resource
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/**") // 拦截所有接口
.excludePathPatterns("/login"); // 放行登录接口
}
}
1.7 权限接口使用示例(控制器)
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.Map;
@RestController
@RequestMapping("/system")
public class UserController {
@Resource
private LoginService loginService;
// 登录接口(无需权限)
@GetMapping("/login")
public Map<String, Object> login(String username, String password) {
return loginService.login(username, password);
}
// 需登录才可访问
@CheckLogin
@GetMapping("/info")
public String userInfo() {
return "当前登录用户ID:" + UserContext.getUserId();
}
// 需指定权限码才可访问
@CheckPermission("sys:user:list")
@CheckLogin
@GetMapping("/user/list")
public String userList() {
return "查询用户列表成功";
}
// 需指定角色才可访问
@CheckRole("admin")
@CheckLogin
@GetMapping("/user/delete")
public String userDelete() {
return "删除用户成功";
}
// 登出接口
@CheckLogin
@GetMapping("/logout")
public String logout(String token) {
loginService.logout(token);
return "登出成功";
}
}
1.8 手写权限核心优化点(生产适配)
-
密码安全优化:替换明文比对,使用 BCrypt 加密匹配密码,杜绝明文存储
-
权限缓存刷新:角色/权限变更时,清空用户Redis缓存,实现权限实时生效
-
数据权限拓展:基于UserContext获取用户ID/部门ID,AOP切面动态拼接SQL过滤条件,实现水平权限
-
异常统一处理:全局异常捕获权限异常,统一返回 403 权限提示,适配前端状态码
-
Token刷新机制:新增Token续期逻辑,避免频繁过期,提升用户体验
-
防重复登录:登录时清空旧Token,实现多端互踢
1.9 手写权限核心面试考点
-
手写权限的核心流程:拦截器做登录认证、AOP做授权鉴权、ThreadLocal存储用户上下文
-
为什么用ThreadLocal?实现线程隔离,保证多请求用户数据不串参
-
拦截器和AOP的权限分工?拦截器校验登录状态,AOP校验角色/权限码,职责解耦
-
如何实现权限实时更新?清空Redis权限缓存,无需重启服务
-
手写权限和框架权限的区别?底层原理一致,框架封装了通用逻辑,手写更灵活、轻量化
2. 主流权限框架
(1)Shiro(轻量、简单、老牌、无框架绑定)
1.1 核心定位
Apache 开源的轻量级权限安全框架,诞生早、生态成熟,无任何框架侵入性,不强制依赖 Spring 体系,可独立运行,是传统单体项目经典首选权限框架,主打「轻量、简洁、上手零门槛」。
1.2 核心四大核心组件(核心架构)
Subject(主体):权限操作核心入口,代表当前登录用户,所有认证、授权、会话操作都通过 Subject 完成,封装了用户所有权限行为。
SecurityManager(安全管理器):Shiro 核心中枢,统筹管理所有认证、授权、会话、缓存、加密等核心逻辑,类似 SpringMVC 的 DispatcherServlet,负责全局权限调度。
Realm(领域数据源):权限数据桥梁,负责从数据库/缓存查询用户、角色、权限数据,交给 SecurityManager 校验,可自定义实现,适配任意业务权限结构。
FilterChain(过滤器链):基于 Web 过滤器实现全局请求拦截,配置路由权限规则,实现接口、路径级别的统一鉴权。
1.3 核心内置功能:
完整覆盖企业基础权限需求,开箱即用,无需大量自定义开发
-
身份认证:账号密码登录、会话管理、登录状态校验
-
权限授权:角色鉴权、权限码鉴权、资源访问管控
-
数据加密:内置 MD5、SHA、BCrypt 等密码加密工具,支持盐值加密
-
会话管理:支持 Session 会话存储、超时失效、会话绑定
-
缓存机制:内置缓存适配,可整合 Redis 实现权限缓存优化
-
RememberMe 记住我:原生支持免登录持久化会话
1.4 核心优点
-
轻量化、源码简洁、学习成本极低,新手可快速上手落地
-
框架无侵入、解耦性强,不绑定 Spring 生态,普通 JavaWeb 项目也可使用
-
配置简单、核心逻辑清晰,自定义拓展难度低,适配小型、简易权限场景
-
社区成熟、文档丰富、BUG 少,稳定性经过长期企业验证
-
内置工具齐全,密码加密、会话管控、鉴权工具无需自研
1.5 致命缺点(企业逐步淘汰核心原因)
微服务适配差:原生基于 Web 过滤器实现,依赖 Servlet 容器,无原生网关鉴权、分布式会话方案,适配微服务、前后端分离架构需要大量二次开发
高级能力缺失:原生不支持 OAuth2.0、OIDC 单点登录、JWT 令牌、多租户隔离、动态权限策略,无法适配复杂分布式场景
迭代停滞:官方长期版本迭代缓慢,新特性更新少,相较于 Spring Security、Sa-Token 生态严重滞后
数据权限薄弱:原生无数据权限、字段权限支撑,需完全自研 AOP 逻辑实现
并发性能一般:原生会话管理性能有限,高并发场景需深度改造缓存机制
1.6 适配场景
-
传统单体 JavaWeb、SSM 架构后台管理系统
-
小型内网系统、简易 OA、工具类后台、权限逻辑简单的项目
-
无分布式、无单点登录、无多租户需求的轻量化项目
-
新手入门权限框架、学习权限底层原理首选
1.7 常用核心过滤器(企业配置必用)
-
anon:匿名访问,无需登录(放行登录、验证码接口)
-
authc:必须登录认证才可访问
-
roles:校验用户拥有指定角色
-
perms:校验用户拥有指定权限码
-
user:记住我/登录用户均可访问
1.8 面试高频考点
Shiro 三大核心组件作用?Subject 操作入口、SecurityManager 核心调度、Realm 权限数据源
Shiro 和 Spring Security、Sa-Token 的核心区别?Shiro 轻量无侵入、适配单体,后两者更适配微服务、生态更强
为什么微服务项目不推荐用 Shiro?原生不支持分布式会话、网关鉴权、JWT 等微服务核心能力,改造成本过高
Shiro 实现密码加密的核心方案?基于盐值+哈希算法加密,避免明文存储,提升密码安全性
(2)Spring Security(企业级、生态强、Spring官方标准)
1.1 核心定位
Spring 官方原生安全权限框架,是Java微服务、大型分布式、云原生项目的行业标准,无缝整合Spring全家桶,无框架适配冲突。主打「全面、安全、规范、可拓展性极强」,适配从单体项目到大型微服务集群、SaaS多租户、OAuth2单点登录等所有复杂权限场景,是国企、大厂、金融政务系统的主流选型。
1.2 核心架构核心组件
-
SecurityContext(安全上下文):全局存储当前登录用户认证信息、权限信息,基于ThreadLocal实现线程隔离,对应自定义权限体系的UserContext,是所有鉴权逻辑的数据基础。
-
Authentication(认证令牌):封装用户身份认证结果,包含用户主体、凭证、权限列表、认证状态,区分未认证、已认证状态。
-
AuthenticationManager(认证管理器):核心认证调度入口,负责校验账号密码、核验身份凭证,统一处理登录认证逻辑。
-
UserDetailsService(用户数据源):自定义用户数据接口,开发者实现该接口,从数据库/缓存查询用户、角色、权限数据,完成框架与业务数据对接。
-
PasswordEncoder(密码加密器):统一密码加密校验规范,默认适配BCrypt、SHA256、Argon2等安全算法,杜绝明文密码,适配企业密码安全规范。
-
FilterSecurityInterceptor(安全拦截器):核心授权拦截组件,拦截所有请求,校验用户角色、权限、资源访问权限,实现接口级鉴权。
-
SecurityFilterChain(安全过滤器链):Spring Security5.7+ 新版核心,替代传统XML配置,链式配置拦截规则、白名单、权限约束,配置简洁灵活。
1.3 原生全覆盖核心功能
-
基础认证授权:账号密码登录、会话管理、角色鉴权、权限码鉴权、匿名访问拦截
-
高级安全防护:原生内置CSRF防护、XSS防护、接口防重放、会话固定攻击防护
-
分布式会话:支持Spring Session整合Redis,实现分布式会话共享、Token统一管控
-
第三方授权登录:原生支持OAuth2.0、OIDC、SAML协议,适配微信、钉钉、企业微信、第三方系统单点登录
-
JWT令牌适配:无缝整合JWT,实现无状态认证,适配前后端分离、微服务架构
-
精细化权限管控:支持功能权限、数据权限、方法级权限、字段级权限拓展
-
多租户适配:可自定义拓展租户隔离逻辑,适配SaaS多租户系统
-
安全合规能力:支持二次认证、登录锁定、IP白名单、会话过期管控,满足等保三级合规要求
1.4 核心优点(企业首选核心原因)
-
官方原生适配:Spring生态官方组件,与SpringBoot、SpringCloud无缝集成,无版本冲突、无适配坑,长期迭代维护,生态绝对稳定
-
安全等级极高:原生自带各类网络攻击防护,安全规范严格,适配金融、政务、国企等高安全合规场景
-
拓展性天花板:所有核心组件均可自定义重写,支持任意复杂权限场景拓展,无业务场景限制
-
微服务适配完美:原生支持网关鉴权、分布式会话、Feign远程调用权限透传,适配云原生、容器化部署
-
标准统一规范:权限架构、认证流程、安全规则均为行业通用标准,团队协作、项目迭代成本低
-
单点登录能力成熟:OAuth2.0+OIDC官方实现,是企业跨系统SSO单点登录的首选方案
1.5 核心缺点(落地避坑)
-
学习成本高:架构体系庞大、组件繁多、源码复杂,新手入门难度远高于Sa-Token、Shiro
-
配置繁琐:原生默认配置严苛,前后端分离、JWT适配、跨域配置需要大量自定义改造,开箱即用性差
-
冗余度高:小型简单项目使用存在过度设计,开发效率低
-
旧版适配复杂:5.7版本前后配置方式大幅重构,新旧版本代码不兼容,历史项目改造成本高
1.6 精准适配场景
-
大型微服务、分布式集群、云原生架构项目
-
金融、政务、医疗、国企等高安全、强合规系统
-
需要OAuth2.0/OIDC单点登录、跨系统统一认证的平台
-
SaaS多租户、复杂数据权限、精细化场景化权限系统
-
长期迭代、团队协作的大型企业级项目
1.7 常用核心注解(开发必用)
-
@PreAuthorize:方法级前置鉴权,支持SpEL表达式,可校验角色、权限、自定义条件(最常用) -
@PostAuthorize:方法执行后鉴权,适合返回数据后校验权限、过滤数据 -
@PreFilter:请求参数集合过滤,适配批量操作权限管控 -
@PostFilter:返回结果集合过滤,快速实现简易数据权限 -
@Secured:角色权限专属校验注解,简洁高效
1.8 企业标准落地组合方案
生产环境主流搭配:Spring Security + OAuth2.0 + JWT + Redis + Spring Session + 自定义数据权限切面
-
基础认证授权:Spring Security原生实现
-
分布式会话:Spring Session整合Redis,实现会话共享、主动踢下线、Token刷新
-
单点登录:整合OAuth2.0/OIDC实现跨系统免密登录
-
数据/字段权限:自定义AOP切面+MyBatis拦截器,补齐原生短板
-
网关鉴权:Spring Cloud Gateway整合Security,实现全局统一权限拦截
1.9 面试高频终极考点
-
Spring Security核心执行流程?请求经过过滤器链 → 认证校验 → 权限鉴权 → 业务放行/拦截
-
Spring Security和Shiro的核心区别?Security生态更强、适配微服务、安全性更高;Shiro轻量简单、适配单体项目
-
@PreAuthorize注解原理?基于AOP动态拦截方法,通过SpEL表达式动态校验权限
-
如何基于Security实现数据权限?原生仅支持功能权限,需自定义AOP+MyBatis拦截器实现行级数据过滤
-
Spring Security解决的核心安全问题?认证授权、网络攻击防护、会话安全、分布式权限统一管控
-
为什么大型微服务项目首选Spring Security?官方生态适配、安全合规、拓展性强、支持单点登录与多租户
(3)Sa-Token(国产、开箱即用、零侵入、企业主流首选)
1.1 核心定位
国内开源、轻量级、高易用性的Java权限认证框架,专为SpringBoot/SpringCloud生态量身打造,彻底解决Shiro配置繁琐、Spring Security学习成本高的痛点,是目前国内中小型企业、初创项目、快速落地项目的首选权限框架。主打「开箱即用、零配置侵入、功能全覆盖、文档通俗、适配微服务」,兼顾简单性与企业级高级能力,零基础开发者可快速上手落地生产级权限体系。
1.2 核心设计理念
摒弃繁琐的组件配置、复杂的过滤器链组装,以极简API、自动装配、零侵入业务为核心,统一封装认证、授权、会话、安全管控所有能力,开发者仅需少量配置即可实现企业级完整权限体系,无需关注底层鉴权逻辑,大幅提升开发效率。
1.3 核心核心能力(全覆盖、开箱即用)
-
基础认证能力:一键登录、注销、登录状态校验、会话有效期管控、多端登录管控、单用户单点登录/多端互踢
-
多层授权能力:登录鉴权、角色鉴权、权限码鉴权、二级认证、临时权限管控
-
会话高级管控:Token刷新、会话续期、手动踢下线、批量注销、会话绑定设备、IP绑定防护
-
分布式适配能力:无缝适配前后端分离、微服务、SaaS多租户、集群部署,统一Redis会话缓存
-
安全防护能力:原生防重放、防暴力破解、密码错误锁定、异地登录提醒、接口限流防刷
-
单点登录能力:原生支持OAuth2.0、OIDC、CAS单点登录,适配跨系统免密登录场景
-
精细化权限拓展:原生适配数据权限、字段权限、自定义权限策略,无需大量自研改造
-
网关统一鉴权:完美适配Spring Cloud Gateway网关层全局鉴权,支撑微服务全链路权限管控
1.4 核心优势(碾压Shiro、优于Security的核心亮点)
-
极致开箱即用:SpringBoot项目引入依赖即可使用,零繁琐配置,自动装配所有核心能力,5分钟即可完成登录鉴权落地
-
零代码侵入:基于注解+API鉴权,不耦合业务代码,权限逻辑与业务逻辑彻底解耦,后期维护成本极低
-
API简洁易懂:所有能力均提供极简静态API,代码可读性高,新手无学习门槛,团队协作成本低
-
分布式原生支持:默认适配Redis缓存会话,天然支持微服务、集群、前后端分离,无需二次开发适配分布式场景
-
高级能力全覆盖:踢下线、Token刷新、多端互踢、二级认证等企业刚需功能原生支持,无需自研
-
国产生态完善:中文文档详尽、社区活跃、问题响应快,适配国内企业业务场景,无水土不服问题
-
轻量高性能:框架体积小、运行损耗低,鉴权链路短,高并发场景性能优于Shiro、常规Security配置
1.5 固有缺点(落地避坑)
-
行业标准性较弱:相较于Spring Security官方生态,属于第三方开源框架,大型国企、金融顶级合规项目认可度略低
-
底层深度不足:封装度极高,底层原理被屏蔽,深度定制、极致安全改造场景灵活性略逊于Spring Security
-
跨语言适配差:主打Java生态,跨语言、跨异构系统的通用权限标准适配能力弱于Spring Security+OAuth2方案
1.6 精准适配场景(企业主流落地场景)
-
中小型企业后台管理系统、OA、CRM、ERP等常规业务系统
-
前后端分离、微服务、SaaS多租户分布式项目
-
快速迭代、降本提效、追求低维护成本的创业项目、迭代型项目
-
需要快速实现单点登录、多端管控、会话管理的系统
-
新手开发、团队技术栈偏弱,需要快速落地权限体系的项目
1.7 开发核心常用注解(生产必用、全覆盖)
-
@SaCheckLogin:校验用户是否登录,拦截所有匿名访问请求 -
@SaCheckRole("admin"):校验用户是否拥有指定角色,支持多角色或校验 -
@SaCheckRole(value = "admin", mode = SaMode.AND):多角色且校验,适配高权限管控场景 -
@SaCheckPermission("sys:user:list"):校验用户是否拥有指定权限码,精准管控接口/按钮权限 -
@SaCheckSafe:敏感操作二次认证注解,适配高危操作合规需求 -
@SaCheckDisable:账号禁用、封禁校验,拦截已失效账号访问
1.8 企业标准落地组合方案(生产最优)
行业通用最优搭配:Sa-Token + Redis + RBAC + 自定义数据权限切面 + Gateway网关鉴权
-
基础认证授权:Sa-Token原生注解+API快速实现
-
会话管控:Redis统一缓存Token、角色、权限数据,支持动态刷新、踢下线
-
基础权限模型:基于标准RBAC五表结构,实现角色、权限批量管控
-
高级权限:自定义AOP+MyBatis拦截器,拓展数据权限、字段权限
-
微服务全局管控:Gateway整合Sa-Token,实现网关统一鉴权、权限收口
1.9 面试高频终极考点
-
Sa-Token核心优势? 开箱即用、零配置、适配微服务、高级会话能力原生支持、开发效率极高
-
Sa-Token与Shiro区别? Shiro适配单体、配置繁琐、微服务适配差;Sa-Token原生适配分布式、功能更全、使用更简单
-
Sa-Token与Spring Security区别? Security是官方标准、安全性更高、适配顶级合规项目;Sa-Token轻量化、易上手、落地快,适配绝大多数中小企业项目
-
Sa-Token如何实现权限实时刷新? 权限变更后清空Redis权限缓存,无需重启服务,实时生效
-
Sa-Token多端互踢原理?登录时校验用户已存在会话,主动清空旧Token,实现单点登录、多端互踢
-
为什么中小企业首选Sa-Token? 兼顾功能完整性与开发效率,无过度设计,维护成本低,完美适配常规企业权限场景
四、权限核心流程(通用标准、生产级闭环)
Java企业级权限体系的所有操作,都遵循统一通用流程,适配单体架构、前后端分离、微服务分布式架构,是所有权限框架(Sa-Token/Spring Security/Shiro)的底层通用逻辑,分为登录认证闭环、请求鉴权闭环、权限注销闭环三大核心流程,同时包含异常拦截、缓存联动、越权防护全链路,完全覆盖生产落地需求。
1. 完整总流程概览(全链路闭环)
前端请求 → 网关/拦截器统一拦截 → 会话Token校验 → 身份认证解析 → 权限缓存加载 → 多层授权校验(登录/角色/权限码) → 数据权限过滤 → 字段权限脱敏 → 业务逻辑执行 → 日志记录 → 结果返回
核心原则:先认证、后授权,先功能鉴权、后数据过滤,全程后端强制校验,任何环节校验失败直接拦截,杜绝裸奔接口与越权风险。
2. 登录认证核心流程(生成合法会话)
核心目标:校验用户身份合法性,生成可管控的会话令牌,缓存用户权限数据,完成身份确权,为后续所有鉴权提供依据。
-
接收前端凭证:客户端提交账号密码、验证码、动态令牌等身份凭证,同时携带设备信息、IP地址;
-
基础合法性校验:校验账号是否存在、是否禁用/注销、验证码是否有效、登录频次是否合规(防暴力破解);
-
密码安全校验:采用BCrypt算法比对密码,禁止明文、MD5校验,杜绝密码泄露风险;
-
加载用户权限数据:查询数据库,获取用户基础信息、绑定角色、权限码集合、数据权限范围、部门信息;
-
生成会话令牌:企业主流采用 UUID随机Token(可控可作废),微服务场景可搭配JWT承载基础信息;
-
Redis会话缓存落地:将Token、用户信息、角色、权限、数据范围存入Redis,设置过期时间、绑定设备IP,支持续期、踢下线;
-
权限预热缓存:单独缓存用户权限集合,避免每次请求查库,大幅提升鉴权性能;
-
返回会话信息:将Token、用户信息、可访问菜单、权限标识返回前端,前端存储Token用于后续请求鉴权;
-
登录日志归档:记录登录时间、IP、设备、状态,用于安全审计、异常溯源,满足等保合规。
3. 接口请求鉴权核心流程(核心校验闭环)
核心目标:对已登录用户的每一次业务请求,完成身份校验、功能权限校验、数据权限隔离、字段脱敏四层管控,杜绝垂直、水平越权。
-
全局请求拦截:所有接口请求优先经过网关(微服务)/自定义拦截器(单体),白名单接口(登录、验证码、注册)直接放行;
-
Token有效性校验:从请求头解析Token,校验Token是否存在、是否过期、是否被手动作废(黑名单校验);
-
解析用户上下文:从Redis缓存读取用户信息,存入ThreadLocal线程上下文,实现全局线程隔离,避免多请求串参;
-
第一层:登录鉴权:校验用户是否处于有效登录状态,匿名用户直接拦截,返回403未登录异常;
-
第二层:角色鉴权:根据接口注解配置,校验用户是否拥有指定角色(如admin、manager),适配岗位层级管控;
-
第三层:功能权限鉴权:校验用户是否拥有当前接口的权限码(如sys:user:list),拦截无权限的功能操作,防垂直越权;
-
第四层:数据权限过滤:通过AOP切面+MyBatis拦截器,根据用户数据范围(本人/本部门/全部)自动拼接SQL过滤条件,防水平越权;
-
第五层:字段权限脱敏:根据用户权限等级,自动隐藏敏感字段、脱敏手机号/身份证/金额,实现字段级精细化管控;
-
业务逻辑执行:所有权限校验通过后,执行接口核心业务逻辑;
-
请求收尾清理:请求结束后清空ThreadLocal上下文,防止内存泄漏;
-
操作日志记录:记录用户操作行为、请求参数、操作结果,用于安全审计与问题排查。
4. 权限注销流程(会话销毁闭环)
核心目标:主动销毁会话,回收权限,防止账号被盗用,完成权限生命周期闭环。
-
接收登出请求:客户端发起登出操作,携带当前登录Token;
-
校验Token合法性:确认Token有效、用户登录状态正常;
-
销毁Redis会话:删除当前Token对应的Redis会话缓存、用户权限缓存,立即失效登录状态;
-
清空线程上下文:手动清除ThreadLocal存储的用户信息,彻底释放资源;
-
记录登出日志:记录登出时间、IP、设备信息,完善安全审计链路;
-
返回登出结果:通知前端清空本地Token、用户信息,完成登出闭环。
拓展:强制踢下线流程(后台管理员操作):后台作废指定用户Token缓存 → 加入黑名单 → 用户后续请求直接拦截 → 强制跳转登录页,实现权限实时回收。
5. 权限缓存联动流程(性能核心)
企业级权限核心优化逻辑,解决高频查库性能瓶颈,同时保证权限实时生效。
-
登录缓存预热:用户登录成功,一次性缓存角色、权限、数据范围至Redis,有效期同步Token过期时间;
-
日常鉴权走缓存:所有请求鉴权优先读取缓存,无需查询数据库,接口性能大幅提升;
-
权限变更实时刷新:后台修改用户角色、权限、数据范围时,自动清空对应用户权限缓存;
-
缓存自愈机制:缓存失效/清空后,用户下次请求自动重新加载权限并缓存,无需手动干预。
6. 全流程异常拦截机制(生产安全兜底)
权限全流程所有异常统一拦截、统一响应,避免系统报错,保障安全合规:
-
未登录异常:Token为空/过期/无效 → 拦截跳转登录,返回401状态码;
-
角色权限不足:用户无对应岗位角色 → 拦截操作,返回角色权限不足提示;
-
功能权限不足:无接口/按钮权限码 → 拦截,返回403无权限异常;
-
越权访问异常:篡改参数访问他人数据、越级操作高权限接口 → 强制拦截并记录风险日志;
-
会话异常:异地登录、设备变更、多端互踢 → 强制下线并提醒用户。
7. 单体 vs 微服务流程差异(落地必知)
7.1 单体架构流程(简洁轻量化)
拦截器统一拦截 → 本地Redis会话校验 → 单服务内完成身份、权限、数据校验 → 执行业务逻辑,无网关层,权限校验全部在业务服务内部完成。
7.2 微服务架构流程(分布式统一收口)
客户端请求 → Gateway网关统一鉴权(核心收口) → 校验Token、黑名单、租户隔离 → 解析用户信息通过Feign透传下游服务 → 业务服务完成角色、权限、数据权限二次校验 → 执行业务逻辑。
核心规则:网关做全局身份拦截,业务服务做精细化权限校验,双层防护杜绝分布式权限漏洞。
8. 面试高频核心考点(流程专项)
-
权限完整执行顺序? 认证登录→会话生成缓存→请求拦截→身份校验→角色/权限鉴权→数据/字段过滤→业务执行;
-
为什么权限要分层校验? 分层拦截、逐级兜底,提前拦截无效请求,提升系统性能,同时精准防护不同越权漏洞;
-
微服务权限为什么要网关收口? 统一全局认证,避免每个服务重复鉴权,统一租户、黑名单、限流规则,简化分布式权限架构;
-
权限缓存刷新原理? 权限变更清空缓存,下次请求自动重载,实现不重启服务、权限实时生效;
-
登录和鉴权的核心区别? 登录是一次性身份确权,鉴权是每一次请求的持续性权限校验。
五、Token 与会话技术
1. 基于 Session(单体应用)
Session 会话认证是传统单体 Java Web 项目的标准认证方案,依托 Servlet 容器原生会话机制实现身份认证与会话管控,无需额外引入令牌框架,是早期 SSM、SpringBoot 单体项目最主流的登录认证实现方式。
1.1 核心原理
服务端(Servlet 容器)开辟专属内存空间生成 HttpSession 会话对象,存储当前登录用户的身份信息、角色权限、登录状态等数据,同时生成唯一 SessionId。服务端将 SessionId 通过 Cookie 下发至客户端浏览器,客户端后续所有请求自动携带该 Cookie,服务端通过 SessionId 匹配对应会话,完成身份识别与鉴权。
1.2 完整登录认证流程
-
客户端提交账号密码,完成身份校验;
-
认证成功后,服务端创建 HttpSession 会话,写入用户信息、权限数据;
-
容器生成唯一 SessionId,自动写入响应 Cookie 返回前端;
-
前端浏览器自动存储 Cookie,后续每次请求自动携带;
-
服务端拦截器根据请求中的 SessionId 匹配会话,校验登录状态;
-
登出时手动销毁 Session,清空服务端会话数据。
1.3 核心优点(单体场景适配优势)
-
原生无依赖:Servlet 容器原生支持,无需引入 Token、JWT 等第三方组件,零额外成本;
-
使用简单高效:API 极简,直接通过 request.getSession() 操作会话,开发成本极低;
-
可控性极强:服务端完全掌控会话,支持主动销毁、强制下线、会话过期管控;
-
安全性基础可靠:会话数据存储在服务端,客户端仅存储 SessionId,不会泄露用户敏感信息;
-
天然防篡改:SessionId 由容器加密生成,客户端无法篡改会话数据。
1.4 致命缺点(无法适配分布式的核心原因)
-
服务端绑定,不支持分布式集群:Session 默认存储在单个服务节点内存中,集群部署时,不同节点无法共享会话,用户请求转发到其他节点会丢失登录状态;
-
前后端分离适配差:依赖浏览器 Cookie 自动携带 SessionId,跨域场景下 Cookie 传递受限,无法适配 App、小程序、纯前端分离项目;
-
服务重启会话丢失:服务重启后内存会话清空,所有用户强制掉线,体验极差;
-
高并发性能瓶颈:大量用户登录会占用服务端内存,会话越多内存开销越大,高并发场景容易出现内存溢出、会话失效等问题;
-
多端适配能力弱:不支持多端登录管控、设备绑定、异地登录识别等高级能力。
1.5 集群解决方案(Session 共享兜底方案)
为解决集群会话丢失问题,传统单体集群项目可通过 Spring Session + Redis 实现 Session 统一共享,将原本存储在内存的 Session 持久化到 Redis,实现多节点会话同步,但该方案属于兼容式改造,并非分布式最优解。
1.6 精准落地场景
-
传统单体 SSM/SpringBoot 后台管理系统;
-
内网小型系统、OA、简易工具平台,无分布式、跨域需求;
-
用户量少、并发低、无需多端适配的静态业务系统。
1.7 面试高频考点
-
Session 认证的核心机制?服务端存会话、客户端存 SessionId,Cookie 自动传递校验身份;
-
为什么 Session 不适合微服务/前后端分离?绑定单服务节点、跨域适配差、集群无法原生共享;
-
Session 集群失效问题如何解决?Spring Session+Redis 实现会话统一共享;
-
Session 与 Token 模式的核心区别?Session 有状态存服务端,Token 无状态、分布式适配更强。
2. JWT(JSON Web Token)
全称:JSON Web Token,基于JSON格式的轻量级、无状态、跨域令牌认证方案,是前后端分离、分布式项目主流的无状态认证载体,可在网络中安全传输用户身份、权限等自定义信息,签名防篡改,广泛应用于微服务、跨系统认证、移动端登录场景。
2.1 JWT 核心结构(三段式,企业必知)
JWT 整体由 Header(头部).Payload(载荷).Signature(签名) 三部分组成,通过小数点分隔,最终生成一串加密字符串,无空格、无特殊字符,可直接在请求头携带。
第一部分:Header(头部)
存储令牌基础配置信息,固定极简结构:
1. alg:加密签名算法(常用 HS256、RS256)
2. typ:令牌类型,固定为 JWT 数据会做 Base64Url 编码,可解码查看,不加密。
第二部分:Payload(载荷|核心数据区)
存储用户身份、时效、业务自定义数据,分为标准公共声明和自定义声明,同样为Base64Url编码,可解码查看,绝对不能存储密码、密钥等敏感数据。 标准公共声明(官方通用字段):
- iss(签发人)、exp(过期时间,核心字段) - sub(主题/用户ID)、aud(接收受众) - iat(签发时间)、jti(令牌唯一ID)
企业自定义声明:userId、username、role、perms、tenantId 等轻量权限信息。
第三部分:Signature(签名|防篡改核心)
由「Header编码字符串 + Payload编码字符串 + 秘钥」通过指定加密算法加密生成。
核心作用:防止令牌数据被篡改,一旦Header或Payload内容被修改,签名校验直接失败,令牌作废,保障身份数据安全。
2.2 JWT 核心认证原理
-
用户登录成功,服务端根据用户信息、过期时间、秘钥生成合规JWT令牌;
-
服务端不存储JWT及用户会话信息,直接将令牌返回给前端;
-
前端存储JWT(LocalStorage/Header),后续所有请求在请求头携带令牌;
-
服务端接收请求后,解析JWT、校验签名合法性、校验过期时间;
-
校验通过后提取用户身份、权限信息,完成鉴权,无需查库校验会话;
-
校验失败(篡改、过期、非法秘钥)直接拦截,返回401未登录异常。
2.3 JWT 核心优点(分布式适配核心优势)
-
完全无状态:服务端无需存储会话数据,极大降低服务内存开销,适配高并发场景;
-
天然分布式友好:不绑定单服务节点,微服务集群、多节点部署无需会话共享,全局通用;
-
跨域适配极强:不依赖Cookie传递,完美适配前后端分离、APP、小程序、跨域名项目;
-
自带数据、减少查库:载荷可携带用户基础信息、权限标识,无需每次请求查询数据库;
-
防篡改、安全性高:签名机制杜绝前端篡改用户身份、权限数据;
-
跨系统通用:标准化协议,支持跨语言、跨平台认证,适配第三方授权、单点登录场景。
2.4 JWT 致命缺点(生产最大坑点)
-
无法主动作废(核心痛点):纯JWT无服务端存储,一旦签发,到期前永久有效,不支持手动踢下线、权限实时回收;
-
数据不可修改:权限变更、用户信息修改后,已签发JWT无法更新,必须等待过期或重新签发;
-
载荷公开可见:Payload仅编码不加密,可直接解码查看所有内容,禁止存储敏感数据;
-
令牌体积偏大:携带数据越多令牌越长,增加请求头传输开销,影响接口性能;
-
过期机制僵硬:只能设置固定过期时间,不支持动态续期、临时失效管控。
2.5 企业生产最优解决方案(JWT 缺陷弥补)
纯JWT无法满足生产级会话管控需求,企业统一采用:JWT + Redis 黑名单 组合方案,兼顾无状态优势与可控性。
-
正常鉴权:优先解析JWT完成身份认证,无需频繁查库;
-
主动作废:用户登出、踢下线时,将未过期JWT的 jti 唯一ID存入Redis黑名单;
-
请求拦截:每次请求先校验黑名单,存在则直接拦截作废令牌;
-
权限刷新:权限变更后拉黑旧令牌,重新签发新令牌,实现权限实时生效;
-
过期清理:设置黑名单过期时间与JWT一致,自动清理无效缓存,避免内存堆积。
2.6 JWT 核心使用场景
-
前后端分离、Vue/React 独立前端项目;
-
微服务、分布式集群、云原生项目;
-
移动端APP、小程序、第三方开放授权登录;
-
跨系统单点登录、OAuth2.0/OIDC 认证场景;
-
高并发、大流量,需要减少服务端存储压力的系统。
2.7 JWT 与 Session 核心对比(面试必背)
|
对比维度 |
Session(有状态) |
JWT(无状态) |
|
存储位置 |
服务端内存/Redis |
客户端本地存储 |
|
会话可控性 |
强,支持主动失效、踢下线 |
弱,纯JWT无法主动作废 |
|
分布式适配 |
差,需额外做会话共享 |
极强,天然适配分布式 |
|
跨域适配 |
差,依赖Cookie、跨域受限 |
极强,请求头携带无限制 |
|
数据安全性 |
高,敏感数据存服务端 |
中等,载荷不可存敏感数据 |
|
性能开销 |
服务端有存储压力 |
服务端零存储,性能更优 |
|
适用架构 |
传统单体项目 |
前后端分离、微服务 |
2.8 面试高频终极考点
-
JWT的三段结构分别是什么?作用是什么? Header配置算法、Payload存用户业务数据、Signature防数据篡改。
-
纯JWT最大的缺陷是什么?如何解决? 无法主动作废、不支持踢下线;搭配Redis黑名单实现会话可控。
-
JWT为什么不能存敏感数据? Payload仅Base64编码、可直接解码查看,无加密保护,极易泄露信息。
-
JWT和Session的核心区别? Session服务端存会话、有状态、可控性强;JWT客户端存令牌、无状态、适配分布式。
-
如何实现JWT令牌续期? 双Token机制(Access Token短期生效+Refresh Token长期刷新),无感续期。
-
为什么JWT需要校验签名? 防止用户篡改载荷中的角色、权限、用户ID等信息,越权操作系统资源。
3. Token + Redis(企业生产最优方案、全域推荐)
核心定位:目前90%以上Java企业级项目(单体/前后端分离/微服务/SaaS)的终极认证方案,完美融合 Session 强可控性、JWT 分布式适配性,彻底解决纯Session分布式缺陷、纯JWT无法主动作废的核心痛点,兼顾安全性、可控性、高性能、高适配性,是生产环境唯一无明显短板的会话认证架构。
核心设计思想:生成随机唯一Token作为客户端身份凭证,核心用户信息、权限数据、会话状态全部存储在Redis服务端,客户端仅持有无业务敏感数据的Token令牌,实现「客户端轻量化、服务端全管控、分布式无缝适配」。
3.1 核心架构组成
-
客户端凭证(Token):采用UUID/Snowflake随机生成32位唯一字符串,无固定算法、无内置敏感数据,杜绝被解码篡改风险,仅作为会话唯一索引Key。
-
服务端存储(Redis):集中存储Token关联的用户ID、账号、角色列表、权限码、数据范围、登录设备、IP地址、过期时间等全量会话数据,支持精准管控。
-
全局拦截机制:网关/拦截器统一拦截请求,通过Token查询Redis校验会话有效性,完成身份认证与权限加载。
3.2 标准生产级执行流程
-
登录确权:用户账号密码校验通过后,清空该用户历史会话(可选多端互踢),生成全局唯一随机Token。
-
Redis缓存落地:以
login:token:{token}为Key,将用户权限、设备信息、会话属性序列化存入Redis,设置动态过期时间(默认2小时,支持续期)。 -
返回客户端凭证:仅将Token字符串返回前端,前端存储在LocalStorage,后续所有请求统一在请求头
Authorization携带。 -
请求鉴权校验:拦截器解析请求头Token,查询Redis判断会话是否存在、是否过期、是否被拉黑。
-
加载用户上下文:Redis读取用户角色、权限、数据范围,存入ThreadLocal,供全局接口、AOP权限切面使用。
-
会话续期机制:用户活跃时自动刷新Redis过期时间,实现「活跃永不过期、闲置自动登出」的企业级体验。
-
登出/踢下线销毁:主动登出或后台踢下线时,直接删除Redis对应Token缓存,会话立即失效,实现秒级权限回收。
3.3 Redis精细化缓存设计(生产规范)
3.3.1 缓存Key设计(统一规范)
-
用户会话Key:
login:token:{tokenStr}→ 存储单端会话全量信息 -
用户在线索引Key:
login:user:{userId}→ 存储用户所有在线Token,用于多端管控、批量踢下线 -
权限缓存Key:
permission:user:{userId}→ 单独缓存用户角色、权限码,拆分会话与权限缓存,提升鉴权性能
3.3.2 缓存过期与续期策略
-
固定过期时间:默认120分钟,适配绝大多数企业系统闲置登出规则。
-
动态续期规则:用户每次有效请求,自动重置Redis过期时间,解决用户操作中途掉线问题。
-
离线兜底清理:依托Redis自带过期淘汰机制,自动清理失效会话,无需人工维护。
3.3.3 多端登录管控策略
-
单端登录(企业默认):同一账号仅允许一台设备在线,新登录自动删除旧设备Token,实现多端互踢。
-
多端登录(适配移动端):允许电脑、手机、平板多端同时在线,分别缓存独立Token,支持单独下线单端设备。
3.4 核心优势(碾压Session、纯JWT的关键)
-
100%分布式适配:会话统一存储Redis,微服务、集群部署、多节点负载均衡无会话丢失问题,天然适配前后端分离、云原生架构。
-
极强可控性:支持秒级踢下线、手动回收权限、批量注销会话、临时会话失效,完美适配企业人员变动、权限调整场景,满足等保合规。
-
安全性拉满:客户端无任何敏感数据,Token为随机字符串无法解码篡改;权限数据全存服务端,彻底杜绝JWT载荷信息泄露风险。
-
高性能低开销:Redis读写性能极高,鉴权仅需一次缓存查询,远优于频繁查库;拆分会话与权限缓存,高并发场景接口响应稳定。
-
无僵硬过期问题:支持动态续期、灵活配置过期时间,解决纯JWT固定过期、无法续期的痛点。
-
适配全场景:兼容单体、微服务、SaaS多租户、移动端、小程序、第三方授权所有业务架构。
3.5 唯一短板与企业解决方案
-
短板:相比纯JWT,需要依赖Redis中间件,增加少量架构部署成本。
-
解决方案:企业项目均默认集成Redis,属于基础设施刚需,无额外部署负担;且缓存架构可大幅提升系统整体性能,收益远大于成本。
3.6 三种认证方案终极横向对比
|
对比维度 |
Session+Redis |
纯JWT |
Token+Redis(最优) |
|
分布式适配 |
一般,需改造适配 |
优秀 |
极致优秀 |
|
会话可控性 |
强 |
极弱(无法主动作废) |
极强 |
|
数据安全性 |
高 |
中(载荷可解码) |
极高 |
|
续期灵活性 |
一般 |
差(固定过期) |
极高(动态续期) |
|
鉴权性能 |
中等 |
高(无查缓存) |
极高(缓存轻量化) |
|
企业落地度 |
老旧项目兼容 |
简单项目临时用 |
90%生产项目首选 |
3.7 生产落地核心规范(避坑必看)
-
禁止Token携带敏感数据:Token仅作索引,所有用户、权限、敏感数据统一存Redis,客户端无任何可解析业务信息。
-
权限缓存实时刷新:后台修改用户角色、权限、数据范围后,立即清空对应用户权限缓存,无需重启服务,权限秒级生效。
-
会话数据轻量化:Redis仅缓存鉴权必需数据,不存储冗余业务数据,减少内存占用、提升读写速度。
-
做好缓存过期兜底:严格设置Token过期时间,结合自动续期+手动清理,避免Redis缓存堆积。
-
请求头统一规范:强制统一Token传递请求头,杜绝参数传Token、Cookie传Token,防止Token泄露、CSRF风险。
3.8 面试高频终极考点
-
为什么Token+Redis是企业最优方案? 兼顾分布式适配、会话可控、数据安全、高性能,解决了Session分布式短板和JWT无法作废、数据泄露的核心问题,无明显短板。
-
随机Token和JWT的核心区别? 随机Token无内置数据、不可篡改、无敏感信息,所有数据服务端可控;JWT载荷可解码、无法主动作废,安全性和可控性更弱。
-
如何实现权限实时刷新? 权限变更清空Redis权限缓存,用户下次请求自动重载最新权限,无需重启服务。
-
多端互踢的实现原理? 基于用户ID索引Key,登录时查询该用户所有在线Token,批量删除旧Token,实现强制下线。
-
会话续期如何实现? 拦截器拦截每一次有效业务请求,自动重置Redis Token过期时间,实现活跃用户永不过期。
六、微服务权限架构(高级)
1. 网关统一鉴权(微服务权限核心收口)
-
核心定位:微服务权限体系的唯一入口、全局收口关卡,彻底解决分布式系统权限散乱、各服务重复鉴权、权限标准不统一、内网接口裸奔等问题,是生产级微服务权限架构的必备核心能力。
-
核心框架:Spring Cloud Gateway(主流)、Zuul(老旧项目,逐步淘汰),本文以企业主流Gateway为例讲解落地方案。
-
核心设计思想:网关做全局身份粗校验,业务服务做精细化权限细校验,双层防护架构,兼顾性能与安全,统一所有微服务的认证、会话、黑名单、租户隔离规则。
1.1 网关统一鉴权核心职责(生产必落地)
-
全局身份认证:拦截所有微服务请求,统一解析Token、校验Token有效性、过期状态、黑名单状态,拦截所有匿名、失效、非法请求,放行合法登录会话。
-
白名单放行管控:统一配置无需鉴权的接口(登录、注册、验证码、静态资源、健康检查接口),全局统一放行,无需每个业务服务单独配置。
-
会话与租户隔离:统一校验租户合法性、会话设备绑定、IP访问限制,实现SaaS多租户、多设备登录管控。
-
请求预处理透传:解析用户ID、账号、角色、权限、租户ID等核心信息,通过请求头透传给下游所有业务服务,避免下游重复解析Token、查缓存,大幅提升分布式鉴权性能。
-
全局安全拦截:统一拦截非法请求、重放攻击、恶意参数,统一限流、熔断、跨域处理,筑牢微服务第一道安全防线。
-
日志统一归集:统一记录请求溯源日志、异常访问日志,方便分布式场景下的问题排查与安全审计。
1.2 网关+微服务完整鉴权链路(生产闭环)
完整流程:
前端请求 → 跨域校验/限流 → 白名单匹配判断 → Token解析与合法性校验 → 黑名单/过期校验 → 用户信息封装请求头 → 路由转发下游服务 → 业务服务二次精细化鉴权 → 执行业务逻辑
-
第一层:网关粗校验(全局拦截):只校验「是否合法登录用户」,拦截未登录、Token失效、拉黑、非法篡改的请求,不做精细角色、权限码校验,保证网关转发高性能。
-
第二层:服务细校验(业务兜底):下游业务服务接收网关透传的用户上下文,完成角色权限、功能权限、数据权限、字段权限的精细化校验,杜绝权限越权。
1.3 核心实现原理(Gateway过滤器机制)
基于Gateway全局过滤器 GlobalFilter + 有序过滤器链实现统一鉴权,通过自定义过滤器优先级,保证鉴权逻辑优先于路由、业务逻辑执行,核心执行顺序:
-
优先级最高:跨域、限流、非法参数拦截
-
次优先级:白名单接口匹配放行
-
核心流程:Token解析、会话校验、黑名单校验
-
后置流程:封装用户上下文、路由转发、日志记录
1.4 关键落地细节(生产避坑)
-
内网信任机制:下游业务服务只信任网关透传的请求头,禁止直接解析前端Token,防止绕过网关直接访问内网接口。
-
请求头防篡改:网关透传的用户、租户信息添加加密签名,下游服务校验签名合法性,防止恶意伪造用户身份越权。
-
空请求头拦截:拦截无Token、非法Token、格式错误的请求,统一返回401未登录异常。
-
黑名单实时拦截:联动Redis黑名单,实现踢下线、权限回收后,用户请求秒级拦截,无需等待Token过期。
-
多端会话统一管控:网关统一识别移动端、PC端、小程序Token,统一管控多端登录、互踢、失效规则。
1.5 网关与业务服务权限分工(企业标准)
|
校验层级 |
网关层(全局) |
业务服务层(局部) |
|
核心能力 |
身份合法性、会话有效性、黑名单、租户隔离、白名单放行 |
角色鉴权、权限码鉴权、数据/字段权限、操作风控 |
|
校验粒度 |
粗粒度、全局通用 |
细粒度、业务定制化 |
|
核心作用 |
拦截无效请求、减轻下游服务压力、统一权限标准 |
防垂直/水平越权、精细化管控业务资源 |
|
性能影响 |
极低,统一缓存查询、无复杂逻辑 |
中等,含AOP切面、SQL过滤逻辑 |
1.6 常见落地坑点与解决方案
坑点1:绕过网关直接访问微服务接口
解决方案:内网服务端口不对外暴露,仅开放网关访问端口,配合服务间IP白名单、注册中心内网隔离,彻底杜绝直访。
坑点2:下游服务重复解析Token、重复查库
解决方案:网关一次性解析缓存用户信息,通过请求头透传,下游直接读取上下文,无需重复解析校验。
坑点3:权限变更后网关未实时生效
解决方案:权限变更清空Redis权限缓存,网关下次请求自动加载最新权限数据,实现秒级刷新。
坑点4:请求头伪造用户信息
解决方案:网关对透传参数加密签名,下游服务校验签名合法性,非法签名直接拦截。
1.7 面试高频终极考点
-
为什么微服务必须做网关统一鉴权? 避免每个服务重复编写鉴权逻辑,统一全局权限标准,拦截非法请求、保护内网服务,实现分布式权限统一管控,提升整体安全性与开发效率。
-
网关鉴权能不能替代业务服务鉴权? 不能。网关仅做登录态、会话合法性粗校验,无法实现角色、权限码、数据范围的精细化业务鉴权,必须双层校验兜底。
-
如何防止绕过网关直接访问微服务? 外网仅暴露网关端口,内网服务私有化部署、限制外网访问,配合IP白名单、请求签名双重防护。
-
网关鉴权核心流程是什么? 拦截请求→白名单判断→Token解析校验→黑名单/过期校验→封装用户上下文→路由转发→下游精细化鉴权。
-
多服务权限不一致如何解决? 基于网关统一鉴权+独立权限中心,全局统一权限标准、统一缓存、统一会话管控,杜绝各服务权限规则混乱。
2. 权限中心(独立服务|微服务架构核心底座)
核心定位:权限中心是微服务架构下的统一身份与权限管控中台,彻底解决多服务权限冗余、标准不统一、数据割裂、维护混乱的问题。将用户、角色、权限、数据规则、租户体系等通用权限能力抽离为独立微服务,所有业务服务统一对接权限中心,实现一次搭建、全服务复用,是大型分布式、SaaS多租户、集团化系统的标准落地架构。
核心设计思想:权限能力下沉、业务服务轻量化、全局标准统一、权限数据中心化管控,彻底摒弃单体服务各业务模块自行维护权限的混乱模式。
2.1 权限中心核心职责(企业全覆盖)
-
统一身份管控:集中管理全平台用户、账号、部门、岗位、租户信息,统一账号新增、禁用、注销、密码重置等账号生命周期管理。
-
统一权限配置:集中维护角色、菜单、接口权限、按钮权限、数据权限规则,支持可视化配置、权限批量分配、角色层级管理。
-
统一鉴权服务:提供标准化RPC/HTTP鉴权接口,为所有下游业务服务提供身份校验、角色匹配、权限码校验、数据范围查询能力。
-
统一缓存管控:全局维护用户权限、角色、数据范围缓存,统一实现权限变更实时刷新、会话失效、踢下线等操作。
-
统一安全审计:集中记录全平台登录日志、权限操作日志、越权访问日志、敏感操作日志,支撑安全审计与问题溯源。
-
统一单点登录:集成OAuth2.0/OIDC/LDAP,支持跨系统、跨平台单点登录,适配集团企业统一身份体系。
2.2 权限中心整体架构分层
采用分层架构设计,职责清晰、解耦彻底,适配高并发、高可用分布式场景:
-
接入层(网关对接):接收网关透传的用户请求信息,承接全局统一认证后的精细化权限预处理,对接网关黑名单、会话管控体系。
-
接口服务层:对外暴露HTTP/Feign RPC接口,供网关、各业务服务调用,包含身份校验、权限查询、数据范围获取、用户信息查询等核心接口。
-
核心业务层:实现角色管理、权限分配、数据规则配置、用户关联、租户隔离、权限缓存刷新等核心业务逻辑。
-
缓存层:基于Redis实现权限、角色、会话数据缓存,支撑秒级鉴权、权限实时刷新、多端会话管控。
-
数据持久层:统一维护权限体系数据库表,持久化用户、角色、权限、关联关系、数据规则等核心数据。
2.3 权限中心核心对外接口(生产通用)
所有业务服务通过Feign远程调用权限中心接口,无需重复开发权限逻辑,核心接口如下:
-
身份校验接口:校验Token有效性、用户登录状态、账号是否禁用/注销。
-
用户信息查询接口:根据用户ID获取用户基础信息、部门、岗位、租户信息。
-
角色权限查询接口:批量获取用户绑定角色、拥有的全部权限码、可访问菜单列表。
-
数据范围查询接口:获取用户对应的数据权限范围(本人/本部门/全部/自定义)。
-
权限校验接口:传入用户ID+权限码/角色标识,批量校验是否拥有对应权限。
-
会话管控接口:实现踢下线、批量注销会话、清空用户权限缓存等操作。
2.4 权限中心+微服务完整交互流程
-
用户登录阶段:用户提交登录请求 → 网关拦截校验 → 转发至权限中心 → 权限中心校验账号密码、生成Token、缓存权限数据、返回登录结果。
-
业务请求阶段:用户携带Token请求业务接口 → 网关统一粗校验(登录态、黑名单) → 透传用户信息至业务服务。
-
精细化鉴权阶段:业务服务通过Feign调用权限中心接口 → 校验角色/权限码、获取数据范围 → 完成功能权限+数据权限双重校验。
-
权限变更阶段:管理员在权限中心修改角色、权限、数据规则 → 自动清空对应用户缓存 → 下游服务下次请求自动加载最新权限。
-
登出管控阶段:用户登出/后台踢下线 → 权限中心删除Redis会话缓存 → 全局立即失效用户登录状态与权限。
2.5 权限中心核心优势(解决微服务痛点)
-
统一标准,消除混乱:全平台统一权限码规范、数据范围规则、鉴权逻辑,杜绝各业务服务权限标准不一致问题。
-
代码复用,降本增效:业务服务无需重复开发权限模块,直接依赖权限中心接口快速实现鉴权,大幅减少重复代码。
-
统一维护,极简运维:权限配置、账号管理、缓存刷新、安全审计全部集中管控,无需逐个服务运维,维护成本极低。
-
极致安全,全局可控:全局权限统一收口,权限变更实时生效,会话可随时回收,彻底杜绝分布式权限漏洞。
-
适配多租户,扩展性强:天然支持SaaS多租户隔离,可快速适配集团化、多业务线、复杂组织架构场景。
2.6 权限中心专属数据库表结构(拓展RBAC五表)
在基础RBAC五表基础上,拓展微服务、多租户、数据权限专属表,构成权限中心完整数据表体系:
-
sys_tenant(租户表):SaaS多租户隔离核心,存储租户信息、过期时间、状态。
-
sys_dept(部门表):存储组织架构、上下级部门关系,支撑数据部门范围过滤。
-
sys_post(岗位表):关联用户与岗位,支撑岗位维度权限管控。
-
sys_menu(菜单表):存储前端菜单、路由、功能入口,关联权限码。
-
sys_resource(接口资源表):登记全平台所有业务接口,统一绑定权限码,实现接口权限管控。
-
sys_data_scope(数据权限配置表):存储角色/用户自定义数据范围、可访问部门列表。
-
sys_login_log(登录日志表):记录全平台用户登录、登出、异地登录、设备信息。
-
sys_oper_log(操作日志表):记录权限配置、角色分配、数据操作、越权访问等敏感行为。
2.7 落地避坑核心规范
-
权限数据单向依赖:所有业务服务禁止私自存储权限、角色、用户数据,全部实时/缓存依赖权限中心,避免数据不一致。
-
缓存双向联动:权限中心变更配置后,不仅清空自身缓存,还需同步通知网关、业务服务清空本地缓存,保证全局权限一致。
-
接口容错降级:权限中心故障时,业务服务开启容错机制,避免全平台鉴权瘫痪,保障核心业务可用。
-
内网接口加密:权限中心所有鉴权接口仅对内网开放,开启接口签名、IP白名单校验,禁止外网直接访问。
2.8 面试高频终极考点
-
微服务为什么需要独立权限中心? 统一全平台权限标准,抽离通用权限能力,解决多服务权限冗余、维护混乱、数据割裂问题,适配分布式架构。
-
权限中心和网关鉴权的分工? 网关做全局登录态粗校验、请求收口;权限中心做精细化角色、权限、数据范围鉴权,双层防护、各司其职。
-
如何保证多服务权限数据一致性? 权限数据统一由权限中心管控,权限变更全局清空缓存,业务服务不持久化权限数据。
-
权限中心故障如何兜底? 配置熔断降级策略,缓存兜底最新权限数据,保障核心业务不中断。
-
权限中心核心价值是什么? 权限能力中台化、全局标准统一、降本增效、筑牢分布式系统权限安全防线。
3. 全链路安全(微服务生产级终极防护)
-
3.1 Token 全链路安全管控
-
3.2 Feign 内部调用安全透传
-
3.3 内网接口防绕过、防直访防护
-
3.4 接口签名 & 防重放攻击
-
3.5 全链路数据防篡改 & 安全兜底机制
3.1 Token 全链路安全管控
Token是分布式系统身份流转的核心载体,全链路严格管控可杜绝90%以上的身份伪造、会话泄露风险,为微服务安全第一道防线。
-
统一传递规范:全局强制通过
Authorization: Bearer {token}请求头传递Token,禁止URL参数、Cookie、请求参数传递,避免Token日志泄露、CSRF窃取、参数劫持风险。 -
Token 传输加密:生产环境全站HTTPS加密传输,杜绝明文传输被抓包窃取、中间人劫持篡改。
-
Token 时效精细化管控:采用「短期AccessToken + 长期RefreshToken」双令牌机制,AccessToken有效期2小时用于日常鉴权,RefreshToken有效期7天用于无感续期,避免长期令牌被盗带来的持久化风险。
-
Token 绑定设备指纹:登录时生成设备唯一指纹(设备ID+UA+IP),绑定至Redis会话信息,每次请求校验设备指纹,杜绝Token异地盗用、劫持复用。
-
失效Token永久拦截:登出、踢下线、权限变更后,Token立即加入Redis黑名单,配合过期自动清理机制,实现会话秒级失效,无残留安全隐患。
3.2 Feign 内部调用安全透传
微服务内部Feign远程调用默认丢失用户上下文,会导致内部接口鉴权失效、权限丢失,需通过全局拦截器实现安全透传,保障链路权限一致性。
-
自定义Feign全局请求拦截器:拦截所有Feign调用,从当前线程ThreadLocal中获取网关透传的用户ID、租户ID、角色、权限、设备指纹等上下文信息,自动封装到内部请求头,实现全服务链路上下文无缝传递。
-
内部请求头加密签名:对透传的用户、租户核心参数进行对称加密+签名,防止链路传输过程中被篡改、伪造身份。
-
上下文隔离兜底:异步线程、定时任务、MQ消费场景,手动绑定用户上下文,避免空上下文导致的鉴权异常或权限越权。
-
禁止前端直接透传内部参数:所有内部权限上下文参数,仅允许网关、服务内部生成传递,前端传入的上下文参数一律拦截清空,杜绝前端伪造用户身份。
3.3 内网接口防绕过、防直访防护
微服务内网接口无外网访问限制时,极易出现绕过网关、直接IP+端口访问内网接口的高危漏洞,需多层隔离防护。
-
端口外网隔离:所有业务服务、权限中心仅开放内网端口,外网仅暴露网关端口,服务器防火墙、云安全组配置白名单,禁止外网直接访问微服务节点。
-
网关信任机制校验:业务服务新增「网关专属请求头标识」,仅认可网关携带的合法标识请求,无标识、标识非法的直访请求直接拦截返回403。
-
内网IP白名单管控:配置服务集群内网IP白名单,仅允许网关、注册中心、权限中心内网IP访问业务接口,陌生IP一律拦截。
-
接口内外网区分:核心业务、数据权限接口标记为内网接口,仅允许网关转发访问;开放接口单独配置白名单,严格区分内外网访问权限。
3.4 接口签名 & 防重放攻击
针对接口篡改、请求复用、恶意刷接口等攻击,通过签名机制+时间戳校验实现全链路防重放、防篡改。
-
接口签名规则(企业通用):请求参数排序 + 时间戳 + 随机nonce + 服务秘钥,拼接后MD5/SHA256加密生成签名,随请求携带。服务端按照相同规则重算签名,对比一致方可放行。
-
防重放核心机制:请求携带时间戳(5分钟有效期)+ 唯一随机串nonce,服务端Redis缓存已使用nonce,过期自动清理,杜绝同一请求重复提交、恶意重放刷接口。
-
分级签名管控:高危接口(转账、删数据、导出、权限分配)强制签名校验,普通查询接口可配置放行,兼顾安全性与性能。
-
签名异常拦截:签名错误、参数篡改、时间戳过期、nonce重复的请求,直接拦截并记录安全日志,触发风险告警。
3.5 全链路数据防篡改 & 安全兜底机制
-
请求参数全局校验:统一参数脱敏、非法字符过滤、SQL注入拦截、XSS脚本过滤,从源头杜绝恶意参数攻击。
-
权限双层兜底校验:网关粗校验+业务服务细校验永不失效,禁止任何接口跳过鉴权逻辑,杜绝接口裸奔。
-
敏感数据链路脱敏:手机号、身份证、金额、隐私信息在接口返回、链路传递、日志打印全环节脱敏,禁止明文传输、明文日志留存。
-
异常安全兜底:鉴权异常、链路异常、服务降级时,默认拒绝所有权限操作,遵循「默认禁止原则」,不放行任何未知请求。
-
全链路日志审计:登录、鉴权、权限变更、敏感操作、越权访问、签名异常全量记录日志,包含IP、设备、时间、操作内容,支持安全溯源与等保合规。
3.6 面试高频终极考点
-
微服务为什么要做Feign上下文透传? 微服务远程调用会丢失ThreadLocal用户上下文,导致内部接口鉴权失效、权限丢失,引发越权漏洞。
-
如何防止绕过网关直接访问内网接口? 外网隔离内网端口+网关专属请求头校验+内网IP白名单三重防护,彻底杜绝直访漏洞。
-
接口防重放的核心实现思路? 时间戳控制请求有效期+随机nonce唯一标识+Redis缓存去重,防止请求复用攻击。
-
Token为什么禁止URL传递? URL参数会被服务器日志、浏览器记录、代理缓存留存,极易造成Token泄露,引发账号被盗风险。
-
全链路安全的核心思想是什么? 身份可溯源、数据不可篡改、请求不可复用、内网不可直访、异常默认拦截,全链路闭环防护。
七、功能权限实现方案
1. 菜单权限(企业级完整落地方案)
核心定位:菜单权限属于功能权限的顶层粒度,是用户进入系统后最直观的权限管控形式,核心解决「用户能看到哪些页面、能访问哪些路由」的问题,依托RBAC模型实现动态配置、按需展示,是前后端分离权限体系的基础核心能力。
核心设计思想:后端统一管控菜单资源、绑定角色权限,前端不写死路由,完全根据当前用户权限动态渲染菜单、过滤路由,实现「不同角色、不同菜单视图」。
1.1 菜单核心数据结构(数据库落地)
依托系统sys_menu菜单表,企业标准核心字段,支撑所有菜单权限场景:
-
menu_id:菜单唯一主键ID
-
parent_id:父菜单ID,0为顶级菜单,支撑多级菜单嵌套(目录→菜单→按钮)
-
menu_type:菜单类型(D目录、M菜单、B按钮),区分层级资源
-
menu_name:菜单名称(前端展示文案)
-
path:前端路由地址(浏览器访问路径)
-
component:前端组件路径(对应页面vue组件地址)
-
permission:权限标识(核心!对应
模块:功能:操作权限码,关联接口权限) -
icon:菜单图标
-
sort:菜单排序权重,控制前端展示顺序
-
visible:是否可见(0显示、1隐藏),支持配置后台隐藏但可访问的路由
-
status:菜单状态(0正常、1禁用),禁用后所有用户无法访问
1.2 菜单层级规范(企业统一标准)
所有后台系统菜单统一遵循「三级层级架构」,规范清晰、适配性强:
-
一级:目录(D):仅做分类聚合,无具体页面,如「系统管理」「用户中心」
-
二级:菜单(M):具体业务页面,可路由访问,如「用户管理」「角色管理」
-
三级:按钮(B):页面内操作按钮,无独立路由,归属对应菜单,关联按钮权限码
1.3 完整权限联动流程(生产闭环)
基于RBAC模型,实现「角色绑定菜单→用户继承角色菜单权限」的完整链路:
-
资源配置阶段:管理员在权限中心录入所有目录、菜单、按钮资源,绑定对应权限码,完成系统资源登记
-
角色授权阶段:给指定角色勾选可访问的菜单/目录,建立「角色-菜单」关联关系
-
用户赋权阶段:用户绑定对应角色,自动继承该角色所有菜单权限
-
登录加载阶段:用户登录成功后,后端根据用户ID查询绑定角色,汇总所有有权限的菜单数据,过滤禁用、隐藏资源
-
前端渲染阶段:前端接收后端返回的菜单树,动态生成侧边栏菜单,同时动态注册路由,拦截无权限路由访问
1.4 后端核心实现逻辑
-
权限过滤:查询菜单时,自动过滤掉用户无权限、禁用、隐藏的菜单资源,仅返回合法可访问菜单
-
树形结构封装:将扁平化的菜单数据,递归组装为父子嵌套树形结构,适配前端菜单渲染
-
路由权限兜底:配合拦截器,校验用户访问的路由地址是否在自身权限菜单范围内,防止前端路由绕过
-
权限实时刷新:角色菜单权限变更后,清空用户权限缓存,用户重新登录或刷新页面即可生效最新菜单
1.5 前端核心动态渲染方案
-
路由不写死:摒弃前端静态配置路由的方式,核心业务路由全部由后端动态返回
-
动态注册路由:页面初始化时,请求后端菜单接口,获取权限路由列表,通过
addRoute动态注册路由 -
侧边栏动态渲染:基于后端返回的菜单树,递归遍历生成侧边栏目录、菜单,无权限资源自动隐藏
-
路由白名单兜底:仅保留登录、404、首页等公共路由,其余路由全部权限管控
-
无权限拦截:用户手动输入无权限路由地址,前端路由守卫直接拦截,跳转403无权限页面
1.6 特殊场景落地方案
-
隐藏菜单场景:部分页面无需展示在侧边栏(如详情页、弹窗页),配置菜单
visible=1,后端正常返回路由权限,前端隐藏菜单入口,支持跳转访问 -
多角色菜单叠加:用户绑定多个角色时,菜单权限自动取并集,合并所有角色的可访问菜单,去重后渲染完整菜单
-
租户菜单隔离:SaaS多租户系统,可配置租户专属菜单,不同租户登录后展示差异化菜单,实现租户资源隔离
-
菜单按需禁用:临时下线业务模块时,直接禁用对应菜单,所有用户统一失效,无需逐个修改角色权限
1.7 生产避坑核心要点
-
禁止前端硬编码权限:菜单显隐、路由权限必须后端兜底,前端仅做展示渲染,防止手动篡改前端代码绕过权限
-
菜单与权限码强绑定:每个菜单必须配置唯一权限码,关联对应接口权限,避免菜单可见但接口无权限的适配问题
-
杜绝死循环菜单:后台配置菜单时校验父子层级,禁止自己嵌套自己,防止树形递归渲染死循环
-
权限缓存同步更新:菜单新增、修改、删除、权限变更后,必须清空全局权限缓存,避免用户缓存旧权限数据
-
404路由后置拦截:动态路由注册完成后再匹配404,防止正常权限路由被误拦截
1.8 面试高频考点
-
菜单权限的实现原理? 基于RBAC模型,角色绑定菜单资源,用户继承角色权限,后端动态过滤菜单树,前端动态渲染路由和侧边栏。
-
为什么菜单权限不能只靠前端控制? 前端路由可手动篡改、手动输入路径绕过,必须后端校验路由权限、兜底拦截越权访问。
-
多角色用户菜单权限如何叠加? 自动合并多个角色的菜单权限,去重后取权限并集,展示全部可访问资源。
-
隐藏菜单和禁用菜单的区别? 隐藏菜单仅前端不展示,仍可访问;禁用菜单彻底失效,无任何访问权限。
-
菜单权限和接口权限的关联关系? 菜单对应页面路由,绑定对应权限码,页面内所有接口复用该权限体系,实现页面与接口权限统一管控。
2. 接口权限(后端核心兜底、防垂直越权关键)
核心定位:接口权限是后端最终安全底线,属于功能权限的核心粒度,用于管控后端所有 API 接口的访问权限,彻底解决垂直越权漏洞。菜单、按钮权限仅做前端展示控制,接口权限是唯一能防止接口裸奔、越级调用的核心手段,所有企业项目必须强制落地。
核心设计思想:基于 RBAC 权限体系,将系统所有接口统一绑定标准权限码,通过拦截器/AOP 切面拦截所有请求,校验当前登录用户是否拥有接口对应权限,无权限直接拦截抛出 403 异常,实现接口级精细化访问管控。
2.1 接口权限核心约束规范(企业强制)
-
全接口登记原则:系统所有业务接口必须统一录入权限中心,绑定唯一权限码,未登记的接口默认禁止访问,杜绝接口裸奔。
-
权限码唯一绑定:严格遵循
模块:功能:操作规范,一个接口对应一个专属权限码,增删改查操作权限相互独立,粒度最小化。 -
后端强制校验原则:无论前端是否展示按钮、菜单,后端接口必须独立鉴权,前端展示仅做交互优化,不能作为权限依据。
-
白名单例外原则:仅登录、注册、验证码、健康检查等公共接口可配置白名单免鉴权,所有业务接口一律强制鉴权。
2.2 两大主流实现方案(企业分级使用)
(1)注解式鉴权(90%企业主流、推荐首选)
基于安全框架注解实现声明式鉴权,代码优雅、粒度精准、侵入性极低,适配所有业务接口。
主流框架注解适配
-
Sa-Token 注解(国产首选、简洁易用):
@SaCheckPermission("sys:user:add") -
Spring Security 注解(生态更强):
@PreAuthorize("hasPermission('sys:user:add')")
核心使用规范
-
注解直接标记在 Controller 接口方法上,精准管控单接口权限
-
支持多权限校验:多权限默认「或关系」,满足其一即可放行;可配置「且关系」需全部满足
-
超级管理员默认拥有所有接口权限,自动跳过鉴权校验
示例代码(生产标准)
/**
* 新增用户接口
* 仅拥有 sys:user:add 权限的用户可访问
*/
@PostMapping("/user/add")
@SaCheckPermission("sys:user:add")
public Result addUser(@RequestBody User user) {
// 业务逻辑
return Result.success();
}
(2)路径匹配鉴权(全局统一管控、适配批量接口)
基于 Spring 拦截器/过滤器,拦截所有请求,通过请求 URL 匹配预设的权限规则,无需逐个接口加注解,适合批量统一管控的接口场景。
核心实现逻辑
-
权限中心维护「URL路径-权限码」映射关系,统一配置接口权限规则
-
全局拦截器拦截所有请求,解析当前请求 URL
-
根据 URL 匹配对应权限码,校验用户是否拥有该权限
-
适配批量接口统一权限、通用模块权限管控场景
优缺点对比
-
优点:无需侵入业务代码,批量接口统一管控,配置灵活
-
缺点:URL 变更需同步修改权限配置,粒度不如注解精准,易出现匹配错误
2.3 接口权限完整校验流程(生产闭环)
-
客户端携带 Token 发起接口请求,网关完成统一登录态粗校验,放行合法请求
-
请求进入业务服务,拦截器捕获请求,解析当前请求 URL、接口方法
-
获取当前登录用户的权限码缓存列表(从 ThreadLocal/Redis 获取,无需重复查库)
-
匹配接口绑定的权限码,校验用户是否拥有对应访问权限
-
权限校验通过,执行业务逻辑;校验失败,统一捕获异常,返回 403 无权限提示
-
记录接口访问日志、越权访问日志,用于安全审计
2.4 多权限叠加与特殊权限规则
-
多角色权限合并:用户绑定多个角色时,自动合并所有角色的接口权限码,取并集放行,权限范围最大化
-
权限通配符适配:超级管理员配置
*通配权限,默认拥有系统所有接口访问权限 -
临时权限兜底:支持为用户单独配置临时接口权限,适配临时运维、临时审批场景
-
接口权限降级:核心业务接口可配置权限降级策略,权限服务异常时,放行核心操作、拦截高危操作
2.5 生产落地避坑核心要点
-
禁止接口无权限码:所有新增业务接口,必须同步配置权限码并添加鉴权注解,杜绝新增接口裸奔
-
禁止前端权限兜底:绝对不能仅依靠前端按钮隐藏控制接口权限,后端必须独立鉴权,防止手动调用接口越权
-
URL 动态适配:接口路径修改、新增接口后,及时同步更新权限配置,避免权限失效或误拦截
-
白名单严格管控:白名单仅放行公共接口,禁止将业务操作接口加入白名单,防止权限漏洞
-
权限缓存及时刷新:角色、接口权限变更后,立即清空用户权限缓存,保证权限秒级生效
2.6 接口权限与菜单/按钮权限联动关系
-
联动逻辑:前端菜单、按钮的权限标识,必须和后端接口权限码保持一致,实现「页面可见、按钮可点、接口可访」权限统一
-
防漏洞兜底:存在前端按钮隐藏,但后端未加权限的高危漏洞,必须保证前端权限展示、后端接口鉴权一一对应
-
渲染联动:用户无接口权限时,前端自动隐藏对应操作按钮、路由菜单,优化用户体验,后端同步拦截接口请求
2.7 面试高频终极考点
-
为什么接口权限必须后端校验? 前端代码可篡改、可绕过,用户可通过接口调试工具直接调用后端接口,仅前端控制权限完全不安全,后端鉴权是唯一安全底线。
-
注解式和路径匹配接口权限的区别? 注解式粒度精准、适配个性化接口;路径匹配批量管控、无代码侵入,生产中优先使用注解式。
-
多角色用户接口权限如何生效? 自动合并所有角色权限码,取并集,只要一个角色拥有对应权限即可放行。
-
如何防止新增接口权限遗漏? 制定代码规范+代码审查,强制所有业务接口必须配置权限码、添加鉴权注解,杜绝接口裸奔。
-
接口权限和垂直越权的关系? 接口权限的核心作用就是防控垂直越权,禁止低权限用户越级调用高权限接口。
3. 按钮权限(精细化前端功能管控、交互级权限落地)
核心定位:按钮权限是功能权限的最小交互粒度,隶属于菜单权限体系下的细分操作权限,核心解决「当前用户在指定页面内,可点击哪些操作按钮、禁用哪些功能入口」的问题。属于前后端协同权限,主打前端交互体验优化,同时配合后端接口权限兜底,杜绝无效按钮展示、防止低权限用户误操作,是企业后台系统精细化权限管控的必备能力。
核心设计思想:依托RBAC权限模型,按钮绑定唯一权限码,用户登录后后端返回当前用户全量权限码,前端通过自定义指令动态匹配权限,实现按钮按需显示、按需禁用,全程无硬编码权限,权限可后台动态配置。
3.1 按钮权限核心特性
-
最小粒度管控:精准控制页面内新增、编辑、删除、导出、审核、重置等单个按钮操作,细化到单点交互功能。
-
前后端协同管控:前端控制按钮显隐/禁用优化交互,后端接口权限做最终安全兜底,双层防护无漏洞。
-
动态可配置:无需修改代码,后台修改角色按钮权限后,用户刷新页面即可生效,适配业务权限动态调整场景。
-
权限联动统一:按钮权限码与菜单、接口权限码严格统一,实现「页面可见、按钮可点、接口可访」的权限闭环。
3.2 企业标准权限码规范(统一复用)
严格遵循全局 模块:功能:操作 权限码规范,与接口权限一一对应,杜绝权限码混乱、不匹配问题,通用规范如下:
-
用户模块:
sys:user:add(新增)、sys:user:edit(编辑)、sys:user:delete(删除)、sys:user:export(导出) -
角色模块:
sys:role:add、sys:role:edit、sys:role:delete、sys:role:assign(分配权限) -
部门模块:
sys:dept:add、sys:dept:edit、sys:dept:delete -
通用业务模块:统一沿用「模块名:页面名:操作名」规则,保证全系统权限码规范统一
3.3 完整落地实现方案(Vue 主流前后端分离)
(1)后端核心支撑
-
菜单表(sys_menu)统一维护按钮资源,菜单类型标记为「B(按钮)」,绑定对应权限码,无独立路由地址。
-
角色授权页面支持勾选对应页面的按钮权限,建立「角色-按钮权限」关联关系。
-
用户登录后,后端汇总用户所有菜单、按钮权限码,统一返回给前端缓存,同时权限变更支持缓存刷新。
-
对应接口强制添加鉴权注解,按钮隐藏不代表接口无权限,后端永久兜底防越权。
(2)前端核心实现(自定义权限指令)
全局注册 v-permission 自定义指令,读取本地缓存的用户权限码数组,动态判断按钮显隐/禁用,企业通用实现方式:
// 全局权限指令注册
app.directive('permission', {
mounted(el, binding) {
// 获取当前按钮绑定的权限码
const permCode = binding.value;
// 获取当前用户缓存的所有权限码
const permList = localStorage.getItem('permissionList') || [];
// 判断是否拥有权限,无权限则移除按钮DOM
if (!permList.includes(permCode)) {
el.parentNode && el.parentNode.removeChild(el);
}
}
})
页面使用示例
<!-- 新增用户按钮:绑定新增权限码 -->
<button v-permission="'sys:user:add'">新增用户</button>
<!-- 删除用户按钮:绑定删除权限码 -->
<button v-permission="'sys:user:delete'">删除用户</button>
<!-- 导出按钮:绑定导出权限码 -->
<button v-permission="'sys:user:export'">导出数据</button>
3.4 两种权限控制模式(企业按需选用)
-
模式一:DOM移除(推荐):无权限时直接移除按钮DOM节点,页面无残留,安全性、整洁度最高,适配绝大多数后台场景。
-
模式二:禁用置灰:无权限时保留按钮位置,设置禁用、置灰样式,仅禁止点击操作,适配需要展示功能入口、仅禁止操作的业务场景。
3.5 按钮权限完整联动流程(生产闭环)
-
管理员在权限中心配置角色对应的页面按钮权限,绑定对应权限码。
-
用户登录系统,后端加载用户角色对应的所有按钮、菜单权限码,缓存并返回前端。
-
前端页面加载时,通过全局权限指令遍历所有按钮,匹配用户权限码。
-
有权限则正常展示按钮,无权限则移除/禁用按钮,优化页面交互。
-
用户点击按钮发起请求,后端接口权限注解二次校验,杜绝前端权限绕过漏洞。
-
后台修改按钮权限后,清空用户权限缓存,用户刷新页面即可生效最新权限。
3.6 特殊业务场景落地方案
-
多按钮批量权限管控:同一页面多个按钮权限独立配置,支持单个角色拥有部分按钮权限,精准差异化管控。
-
按钮权限动态切换:结合业务状态联动权限,如单据审批完成后,自动隐藏「审核、驳回」按钮,无需后端改权限配置。
-
超级管理员权限兜底:超级管理员默认拥有所有按钮权限,自动跳过权限校验,所有功能按钮全部可见可操作。
-
弹窗按钮权限管控:弹窗内操作按钮同样绑定权限指令,统一适配弹窗场景权限管控,无权限弹窗按钮自动隐藏。
3.7 生产落地避坑核心要点
-
严禁前端单一权限管控:按钮权限仅做前端交互优化,必须配套后端接口鉴权,防止用户通过接口调试工具绕过前端按钮限制,直接调用接口越权操作。
-
权限码严格统一:按钮权限码、菜单权限码、接口权限码必须一一对应,避免出现「按钮隐藏但接口可访问、按钮显示但接口无权限」的适配bug。
-
禁止硬编码权限:不允许在前端代码写死角色判断、权限判断,所有权限由后端动态配置,保证权限灵活可改。
-
权限缓存及时刷新:角色按钮权限变更后,必须清空前端本地权限缓存+后端Redis权限缓存,避免用户长期缓存旧权限。
-
空权限兜底处理:用户无任何按钮权限时,页面自动隐藏所有操作入口,避免出现空白按钮、无效功能入口。
3.8 面试高频终极考点
-
按钮权限的实现原理? 基于RBAC模型,按钮绑定标准权限码,用户登录后前端获取权限码列表,通过自定义指令动态控制按钮显隐,后端接口鉴权兜底。
-
为什么按钮权限不能替代接口权限? 前端按钮控制仅为展示层面,可通过代码篡改、接口调试工具绕过,无法保障安全,后端接口鉴权是唯一安全底线。
-
按钮权限、菜单权限、接口权限的关联关系? 三者共用同一套权限码规范,菜单管控页面路由、按钮管控页面交互、接口管控后台访问,层层联动、闭环防护。
-
权限更新后为什么需要刷新缓存? 用户权限码会缓存至前端本地和后端Redis,不刷新缓存会导致权限变更无法实时生效,出现权限滞后问题。
-
多角色用户按钮权限如何叠加? 自动合并多个角色的按钮权限码,取并集,拥有任意角色对应权限即可展示对应按钮。
权限码规范(企业通用)
模块:功能:操作
例:sys:user:list、sys:user:add、sys:user:edit、sys:user:delete、sys:user:export
八、数据权限实现(高级核心、企业重难点)
核心定位:数据权限是企业权限体系最核心、最难落地、面试必考的高级能力,专门解决水平越权漏洞。功能权限控制「能不能操作功能」,数据权限控制「操作时能看到哪些数据」,实现同接口、同角色、不同用户,查询数据结果差异化,是政务、金融、OA、SaaS系统的刚需能力。
核心本质:基于当前登录用户的身份(用户ID、部门ID、角色数据范围),无侵入自动拼接SQL过滤条件,从数据库层面拦截非法数据,彻底杜绝水平越权。
核心落地架构:自定义数据权限注解 + AOP切面预处理 + MyBatis拦截器动态SQL拼接 + ThreadLocal上下文传递,全程零业务代码侵入,适配所有业务接口。
1、核心实现原理与整体流程
-
注解标记接口:业务查询接口添加
@DataScope自定义注解,标识该接口需要开启数据权限过滤 -
AOP切面解析权限:接口请求进入切面,获取当前登录用户ID、部门ID、角色配置的数据权限范围
-
封装过滤参数:根据数据范围规则,生成对应的SQL过滤条件(如 dept_id = 1001、create_by = 10001),存入ThreadLocal上下文
-
MyBatis拦截器拼接SQL:拦截所有SELECT查询SQL,自动拼接上下文的过滤条件,实现数据过滤
-
清空上下文:接口执行完毕,清空ThreadLocal数据,避免内存泄漏、参数污染
2、企业标准五大数据权限范围(全覆盖业务场景)
基于角色配置数据范围,全局统一标准,覆盖100%企业组织架构数据隔离需求,
优先级:自定义数据 > 固定数据范围:
-
1. 全部数据(SCOPE_ALL):超级管理员专属,不拼接任何过滤条件,可查询系统所有业务数据,无数据隔离限制
-
2. 本部门及子部门数据(SCOPE_DEPT_AND_CHILD):部门总监、高管专属,自动拼接
dept_id IN (当前部门及所有子部门ID集合) -
3. 本部门数据(SCOPE_DEPT):部门经理专属,仅拼接
dept_id = 当前用户部门ID,无法查看子部门数据 -
4. 仅本人数据(SCOPE_SELF):普通员工专属,拼接
create_by = 当前用户ID,只能查看自己创建的业务数据 -
5. 自定义数据(SCOPE_CUSTOM):适配复杂组织架构,手动指定角色可访问的多个部门ID,拼接
dept_id IN (自定义部门ID集合)
3、核心代码落地(生产可直接复用)
3.1 自定义数据权限注解 @DataScope
用于标记需要数据权限过滤的接口,支持自定义表别名、用户字段、部门字段,适配多表联查场景
/**
* 数据权限过滤注解
* 支持单表、多表联查自定义字段匹配
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataScope {
/**
* 数据表别名(多表联查时指定,默认空)
*/
String tableAlias() default "";
/**
* 部门ID字段名
*/
String deptField() default "dept_id";
/**
* 创建人用户ID字段名
*/
String userField() default "create_by";
}
3.2 数据权限上下文工具类(ThreadLocal存储)
全局存储数据权限过滤参数,供切面、MyBatis拦截器获取,保证线程隔离、数据安全
/**
* 数据权限上下文工具类
*/
public class DataScopeContext {
// 线程隔离:存储当前数据权限过滤SQL
private static ThreadLocal<String> DATA_SCOPE_SQL = new ThreadLocal<>();
// 设置过滤SQL
public static void setSql(String sql) {
DATA_SCOPE_SQL.set(sql);
}
// 获取过滤SQL
public static String getSql() {
return DATA_SCOPE_SQL.get();
}
// 清空上下文(必须finally执行,防止内存泄漏)
public static void clear() {
DATA_SCOPE_SQL.remove();
}
}
3.3 AOP切面核心处理逻辑
拦截标记@DataScope的接口,根据用户角色数据范围,动态生成对应SQL过滤条件
/**
* 数据权限切面
*/
@Aspect
@Component
public class DataScopeAspect {
// 切入点:所有添加@DataScope注解的方法
@Pointcut("@annotation(com.framework.common.annotation.DataScope)")
public void dataScopePointCut() {}
@Before("dataScopePointCut() && @annotation(dataScope)")
public void doBefore(DataScope dataScope) {
// 1. 获取当前登录用户信息(含部门ID、角色、数据范围)
LoginUser loginUser = SecurityUtils.getLoginUser();
if (Objects.isNull(loginUser)) {
return;
}
// 2. 获取用户角色配置的数据权限范围
Integer dataScopeType = loginUser.getRoleDataScope();
String tableAlias = dataScope.tableAlias();
String deptField = dataScope.deptField();
String userField = dataScope.userField();
// 拼接表别名前缀
String prefix = StrUtil.isNotBlank(tableAlias) ? tableAlias + "." : "";
// 3. 根据数据范围类型生成SQL过滤条件
String sql = "";
switch (dataScopeType) {
// 全部数据:无过滤条件
case 0: sql = ""; break;
// 本部门及子部门
case 1:
sql = prefix + deptField + " IN " + loginUser.getDeptAndChildDeptIdList();
break;
// 本部门数据
case 2:
sql = prefix + deptField + " = " + loginUser.getDeptId();
break;
// 自定义部门数据
case 3:
sql = prefix + deptField + " IN " + loginUser.getCustomDeptIdList();
break;
// 仅本人数据
case 4:
sql = prefix + userField + " = " + loginUser.getUserId();
break;
default: sql = "";
}
// 4. 存入上下文
DataScopeContext.setSql(sql);
}
// 方法执行完毕清空上下文
@After("dataScopePointCut()")
public void doAfter() {
DataScopeContext.clear();
}
}
3.4 MyBatis拦截器动态拼接SQL(核心关键)
拦截所有查询SQL,自动拼接数据权限过滤条件,零侵入业务Mapper、XML
/**
* MyBatis数据权限SQL拦截器
*/
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
@Component
public class DataScopeInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 获取待执行SQL
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
String originalSql = metaObject.getValue("delegate.boundSql.sql").toString().trim();
// 获取数据权限过滤条件
String dataScopeSql = DataScopeContext.getSql();
if (StrUtil.isNotBlank(dataScopeSql) && originalSql.toLowerCase().startsWith("select")) {
// 拼接where条件,支持原有where参数叠加
if (originalSql.contains("where")) {
originalSql = originalSql + " AND " + dataScopeSql;
} else {
originalSql = originalSql + " WHERE " + dataScopeSql;
}
// 覆盖原SQL
metaObject.setValue("delegate.boundSql.sql", originalSql);
}
return invocation.proceed();
}
}
3.5 业务接口使用示例(极简无侵入)
/**
* 分页查询用户数据(自动数据权限过滤)
* 适配多表联查,指定用户表别名u
*/
@GetMapping("/user/list")
@SaCheckPermission("sys:user:list")
@DataScope(tableAlias = "u")
public Result<PageVo<UserVo>> userList(UserQuery query) {
// 纯业务分页查询,无需手动写数据过滤逻辑
PageVo<UserVo> page = userService.selectUserPage(query);
return Result.success(page);
}
4、多场景适配方案(复杂业务落地)
4.1 多表联查适配
多表关联查询时,通过注解 tableAlias 指定数据归属表别名,精准拼接过滤条件,避免字段冲突、过滤失效。例如用户表关联部门表,指定用户表别名,仅过滤用户创建数据。
4.2 超级管理员兜底逻辑
超级管理员角色默认数据范围为「全部数据」,不拼接任何过滤SQL,拥有全量数据查询权限,无需特殊代码适配。
4.3 特殊接口跳过数据权限
全局统计、公共字典、系统配置等无需数据隔离的接口,不添加@DataScope注解,直接跳过数据权限过滤,兼顾安全性与业务合理性。
4.4 数据权限与功能权限联动
先通过接口权限校验用户是否有操作资格(防垂直越权),再通过数据权限过滤数据(防水平越权),双层校验形成安全闭环。
5、生产落地高频坑点与终极解决方案
坑点1:分页总数、条数统计不准确
解决方案:MyBatis分页插件开启「自动适配数据权限SQL」,count查询同步拼接过滤条件,避免分页列表过滤、总数未过滤导致的数据错位。
坑点2:多线程/异步场景数据权限失效
解决方案:ThreadLocal无法传递异步线程上下文,手动将主线程数据权限参数传入异步线程,手动赋值上下文。
坑点3:SQL注入风险
解决方案:禁止直接拼接用户传入参数,仅拼接系统预设的部门ID、用户ID,参数固化无注入风险。
坑点4:权限变更不实时生效
解决方案:角色数据范围变更后,清空对应用户Redis权限缓存,下次请求自动加载最新数据权限规则。
坑点5:子查询、复杂SQL过滤失效
解决方案:优化拦截器SQL解析逻辑,针对子查询、关联查询做适配,优先匹配主表数据字段。
坑点6:上下文内存泄漏
解决方案:切面@After注解强制清空ThreadLocal上下文,保证每次请求结束资源释放。
6、数据权限缓存优化(高并发必备)
-
缓存内容:用户所属部门ID、子部门ID集合、自定义权限部门ID集合、数据范围类型
-
缓存位置:Redis全局缓存 + 本地线程缓存,减少重复查库
-
刷新机制:部门变更、角色数据权限配置变更、用户部门调动,自动清空对应缓存,实现秒级生效
-
性能提升:避免每次接口请求查询部门、权限数据,接口响应速度提升5-10倍
7、面试高频终极考点(必背)
-
数据权限的核心作用? 解决水平越权漏洞,实现同角色不同用户的数据隔离,精准管控用户可查询的数据范围。
-
数据权限核心实现原理? 自定义注解标记接口+AOP解析权限规则+MyBatis拦截器动态拼接SQL,无侵入实现行级数据过滤。
-
数据权限和功能权限的区别? 功能权限防垂直越权(能不能用功能),数据权限防水平越权(能看哪些数据),二者互补。
-
为什么不用代码硬判断实现数据权限? 硬编码冗余度高、维护成本大、无法统一管控,切面拦截全局统一处理,零侵入业务代码。
-
异步任务如何保证数据权限生效? 手动传递ThreadLocal上下文参数,异步线程主动加载数据权限规则。
-
分页数据权限不准如何解决? 让分页count查询和列表查询使用同一条过滤SQL,保证数据统计一致性。
九、安全加固(必备|生产级+等保合规全覆盖)
安全加固是企业Java权限体系的最后一道防线,也是等保2.0合规、线上漏洞防护、面试核心考点。前文的认证、授权、数据权限解决了「权限合规管控」,本章加固方案解决「黑客攻击、恶意刷接口、数据泄露、漏洞利用」等线上安全风险,所有方案均为生产强制落地标准,覆盖身份、接口、数据、请求、链路全维度防护。
1、密码安全加固(杜绝密码泄露、暴力破解)
密码是身份认证的核心入口,明文、弱加密是系统高危漏洞,企业必须强制使用不可逆、带盐值、抗破解的加密算法,禁止MD5、SHA1、SHA256简易加密。
1.1 主流加密算法选型(企业分级)
-
BCrypt(90%企业首选):自带随机盐值、动态算力迭代、不可逆加密,相同密码多次加密结果不同,暴力破解成本极高,适配绝大多数后台系统
-
Argon2(金融/政务高阶):目前行业最安全的密码加密算法,抗GPU算力破解,适配高密级合规系统
-
强制淘汰算法:MD5、SHA1、SHA256(无盐值可彩虹表破解,完全不符合等保要求)
1.2 生产级密码安全规则
-
密码复杂度约束:强制大小写字母+数字+特殊符号,长度≥8位,禁止弱密码(123456、admin123),新用户初始化密码强制首次登录修改
-
加密存储规范:数据库仅存储加密密文,全程无明文传输、无明文日志打印
-
暴力破解防护:密码错误5次锁定账号10分钟,拦截脚本批量刷登录
-
定期密码轮换:高危账号(管理员)强制90天更换密码,杜绝长期静态密码风险
1.3 BCrypt 工具类可直接复用
/**
* 密码加密工具类(生产标准)
*/
public class PasswordUtil {
// 加密算力,适配服务器性能
private static final int BCRYPT_STRENGTH = 12;
// 密码加密(自动生成随机盐值)
public static String encode(String password) {
return BCrypt.hashpw(password, BCrypt.gensalt(BCRYPT_STRENGTH));
}
// 密码校验(明文密码 vs 加密密文)
public static boolean matches(String rawPassword, String encodedPassword) {
return BCrypt.checkpw(rawPassword, encodedPassword);
}
}
2、接口限流防刷(防CC攻击、恶意请求)
系统接口极易被恶意脚本、爬虫、CC攻击高频请求,导致服务雪崩、接口瘫痪,必须通过网关限流+接口粒度限流双层防护,适配普通用户、游客、管理员不同限流策略。
2.1 三层限流架构(企业标准)
-
网关全局限流:基于IP地址限流,单IP每分钟最大请求次数,拦截恶意IP批量请求
-
用户级限流:登录用户基于userId限流,区分普通操作、高危操作差异化限流
-
接口粒度限流:高危接口(登录、导出、删除、转账)单独严格限流,普通查询接口宽松限流
2.2 主流实现方案
-
Redis+Lua限流(推荐):原子性操作,防止限流并发超量,精准控制请求频次,性能高、无并发问题
-
Gateway网关限流:微服务架构首选,统一入口拦截,无需改造业务代码
-
自定义注解限流:针对单个接口灵活配置限流规则,适配个性化业务场景
2.3 限流核心规则
-
匿名游客:限制高频查询、验证码获取、登录请求,防止脚本刷接口
-
普通用户:查询接口宽松限流,导出、提交、修改接口严格限流
-
超级管理员:适度放宽限流,避免运维操作被误拦截
-
限流兜底:触发限流直接返回429请求过于频繁,同时记录风险日志
3、XSS/CSRF 跨站攻击防护
Web系统两大经典高危漏洞,针对前端脚本注入、跨站请求伪造,必须全链路防护,满足等保基础安全要求。
3.1 XSS跨站脚本攻击防护
漏洞原理:攻击者注入恶意JS脚本,窃取用户Cookie、Token、账号信息,冒充用户操作系统。
-
输入过滤:全局拦截请求参数,过滤script、iframe、onload等恶意脚本标签
-
输出转义:前端渲染数据、后端返回数据自动转义特殊字符,杜绝脚本执行
-
请求头防护:配置
X-XSS-Protection开启浏览器自带XSS防护 -
禁止脚本读取敏感凭证:Token存储请求头,禁止存储Cookie,防止JS窃取
3.2 CSRF跨站请求伪造防护
漏洞原理:利用用户已登录状态,诱导用户在恶意页面发起跨站请求,非法操作系统数据。
-
Token校验防护(主流):所有写操作接口(增删改)必须携带前端CSRF Token,后端校验一致性
-
Referer/Origin校验:拦截非可信域名的跨站请求,禁止陌生来源请求
-
Cookie SameSite策略:配置Cookie同源访问限制,杜绝跨站Cookie携带
4、接口签名 & 防重放攻击(高阶防护)
针对接口参数篡改、请求复用、恶意刷接口、中间人攻击,是金融、支付、政务系统必备加固方案,前文微服务安全章节基础上做完整落地补充。
4.1 通用签名规则(全网统一标准)
请求参数字典排序 + 时间戳timestamp + 随机串nonce + 服务秘钥secret,拼接后SHA256加密生成sign,随请求携带。
4.2 防重放核心机制
-
时间戳有效期:请求仅5分钟有效,过期请求直接拦截,防止历史请求复用
-
唯一随机串:每个请求携带唯一nonce,Redis缓存已使用随机串,永久去重
-
参数防篡改:任意参数修改都会导致签名不一致,自动拦截篡改请求
4.3 分级防护策略
-
高危接口(转账、删数据、批量导出、权限分配):强制签名+防重放
-
普通查询接口:可选关闭签名,兼顾安全性与性能
5、Token 全维度安全加固
Token是前后端分离、微服务认证的核心凭证,Token泄露、劫持、过期失控是高频安全漏洞,需全方位管控。
5.1 Token基础安全规则
-
禁止URL传参:Token仅通过Header传递,避免服务器日志、浏览器记录泄露凭证
-
短期有效+自动刷新:AccessToken短期过期(2小时),搭配RefreshToken无感刷新,减少长期Token泄露风险
-
设备绑定:Token绑定设备指纹、IP,异地登录强制二次认证,防止Token劫持复用
-
主动失效机制:支持手动踢下线、批量注销、密码修改强制清空所有登录Token
5.2 JWT漏洞兜底方案
-
纯JWT无状态无法作废,必须搭配Redis黑名单,实现Token主动失效
-
禁止JWT存储敏感数据(密码、手机号),载荷数据公开可解析
-
强制JWT签名校验,禁止空秘钥、弱秘钥配置
6、越权漏洞终极防护(垂直+水平闭环)
越权是线上最高危、最易被检测的漏洞,所有安全加固最终都为了杜绝越权访问,形成双层防护闭环。
6.1 垂直越权防护加固
-
所有接口强制后端鉴权,零接口裸奔,禁止前端权限兜底
-
权限最小化原则,角色默认无任何权限,按需开放
-
高危接口单独增加IP白名单、二次认证加固
6.2 水平越权防护加固
-
所有业务查询接口强制开启数据权限注解,自动SQL过滤
-
禁止业务代码手动拼接查询条件,统一走数据权限切面
-
拦截ID遍历爬取数据行为,异常数据访问触发风控告警
7、敏感数据安全加固(脱敏+防泄露)
7.1 全链路数据脱敏
-
展示脱敏:手机号138****1234、身份证110********1234、邮箱****@163.com
-
日志脱敏:所有接口日志、操作日志禁止打印明文敏感数据
-
传输脱敏:内外网传输敏感数据统一加密,禁止明文透传
7.2 数据操作权限管控
-
数据导出、批量查询、删除等高危操作,强制二次认证+操作日志记录
-
敏感数据仅内网可访问,外网禁止导出、批量查询
8、安全日志审计与风控告警(等保必备)
安全溯源、漏洞排查、等保考核核心,所有敏感操作、异常访问必须全量留痕。
8.1 必录安全日志
-
登录日志:登录成功/失败、IP、设备、时间、登录地点
-
权限日志:角色新增、权限分配、数据范围修改、账号禁用/启用
-
敏感操作日志:删数据、改密码、批量导出、审核驳回、批量操作
-
异常安全日志:越权访问、签名失败、Token非法、限流拦截、暴力破解
8.2 实时风控告警
-
频繁登录失败、异地登录、批量越权访问触发短信/钉钉告警
-
高危接口高频请求、数据批量导出异常触发风控拦截
9、生产安全兜底总则(核心底线)
-
默认拒绝原则:所有未配置权限、未登记接口、异常请求一律拦截放行
-
双层校验原则:前端仅做展示优化,后端永久强制鉴权、数据过滤
-
权限隔离原则:角色互斥、数据隔离、内外网隔离,杜绝权限泛滥
-
可溯源原则:所有操作、权限变更、异常访问全量日志留痕,可审计可追溯
10、面试高频终极考点
-
为什么不用MD5存密码? MD5无盐值易被彩虹表破解,BCrypt自带随机盐值、动态算力,安全性更高,适配生产环境。
-
接口防重放的实现思路? 时间戳控制请求有效期+唯一随机串去重+签名防篡改,杜绝请求复用与参数篡改。
-
XSS和CSRF的区别? XSS是注入恶意脚本窃取信息,CSRF是伪造用户跨站请求,防护方案完全不同。
-
Token为什么需要刷新机制? 短期Token降低泄露风险,刷新机制保证用户无感知续登,兼顾安全与体验。
-
安全加固的核心思想? 全链路闭环防护,事前预防、事中拦截、事后溯源,杜绝越权、攻击、数据泄露三大核心风险。
十、企业级权限架构设计图
# 企业级Java权限完整架构分层图(自上而下全链路闭环)
# 适配:前后端分离、微服务集群、SaaS多租户、等保合规系统
# 核心能力:认证拦截、权限校验、越权防护、数据隔离、安全加固、缓存优化
【客户端层】
├─ Web前端 / 移动端App / 第三方API客户端
└─ 能力:页面路由渲染、按钮显隐控制、请求Token携带、前端交互权限优化
↓↑(HTTP/HTTPS 请求响应)
【网关层(全局统一入口)—— 第一道安全关卡】
├─ 统一请求拦截、全局限流防刷、IP黑名单拦截
├─ Token基础校验、会话有效性校验、跨域处理
├─ 请求头安全校验、非法请求过滤、防重放初步拦截
└─ 路由分发、灰度流量控制
↓↑(放行合法请求,拦截非法请求)
【认证授权核心层(业务服务内)—— 核心权限校验关卡】
├─ 1. 认证模块(Authentication)
│ ├─ 账号密码/验证码/OAuth2登录校验
│ ├─ BCrypt密码解密比对、用户状态校验
│ ├─ Token生成、刷新、失效、设备绑定
│ └─ 登录日志记录、风险登录拦截
│
├─ 2. 授权模块(Authorization)
│ ├─ 登录态校验、角色权限校验(垂直越权防护)
│ ├─ 接口/菜单/按钮功能权限鉴权
│ ├─ 数据权限AOP拦截、动态SQL拼接(水平越权防护)
│ └─ 字段权限脱敏、显隐控制
│
└─ 3. 安全加固模块
├─ XSS/CSRF攻击防护、接口签名防篡改
├─ 高危操作二次认证、风控告警
└─ 安全日志审计、越权异常拦截
↓↑(权限校验通过,进入业务逻辑)
【业务服务层】
├─ 各模块业务接口、业务逻辑执行
└─ 无权限硬编码,完全依赖上层权限框架管控
↓↑(数据交互)
【权限核心支撑层(系统底层)】
├─ 1. 权限模型层(核心基石)
│ ├─ ACL(简易系统)、RBAC0-3(企业主流)
│ ├─ ABAC(动态场景、精细化权限)
│ └─ 数据/字段权限拓展模型
│
├─ 2. 缓存层(性能核心)
│ ├─ Redis存储:用户Token、角色列表、权限码集合
│ ├─ 数据范围规则、黑名单失效Token
│ └─ 权限变更实时刷新、缓存预热
│
└─ 3. 持久化层(数据存储)
├─ 用户/角色/权限/部门数据库表
├─ 数据范围配置、权限关联关系
└─ 安全日志、操作日志、登录日志存储
【全链路闭环规则】
1. 执行顺序:先认证 → 后功能授权 → 再数据授权 → 最后字段脱敏
2. 防护闭环:网关防攻击 + 后端鉴权兜底 + 数据行级隔离 + 日志溯源
3. 核心原则:默认拒绝、最小权限、前后端双重校验、无侵入业务
十一、遗漏的核心模块
遗漏 1:权限架构的分层设计(企业必用)
真实项目不是一堆技术堆在一起,而是严格分层,漏了这层就不是架构。
1. 接入层:网关、过滤器、拦截器
2. 认证层:登录、多因素认证、身份核验
3. 鉴权层:功能权限、数据权限、API权限
4. 权限管理层:RBAC/ABAC、角色、权限配置
5. 安全层:防刷、防越权、加密、审计
6. 会话层:Token、刷新、下线、封禁
7. 基础支撑层:缓存、数据库、消息、配置
遗漏 2:多维度权限体系(企业真实必开)
上版只讲了功能 + 数据,实战必须包含 5 种权限,缺一不可:
-
菜单权限(能看到哪些菜单)
-
按钮权限(能点哪些按钮)
-
接口权限(能调用哪些 API)
-
数据权限(能看到哪些数据)
-
字段权限(能看到哪些字段:手机号、金额脱敏)
✅ 字段权限是 90% 教程会漏的,但金融 / ERP/OA 必用
遗漏 3:权限的生命周期管理
架构不是只做 “鉴权”,还要管权限从创建到销毁:
plaintext
申请 → 分配 → 启用 → 变更 → 回收 → 审计 → 过期
包含:
-
临时权限
-
自动过期权限
-
权限申请 / 审批流
-
权限回收机制
遗漏 4:超级管理员与权限隔离
实战必须有:
-
平台超级管理员
-
租户管理员(SaaS)
-
部门管理员
-
普通角色
-
权限不可越级分配(关键安全规则)
遗漏 5:SaaS 多租户权限架构(企业现在几乎都要)
上版没提,但现在 70% 新项目都是 SaaS。
必须包含:
-
租户隔离(数据库 / 表 / 字段)
-
租户独立角色、独立权限
-
跨租户权限控制
-
租户套餐权限(不同套餐开放不同功能)
遗漏 6:细粒度 API 权限(接口级安全)
实战不是只靠路径匹配,必须包含:
-
请求方法权限(GET/POST/PUT/DELETE)
-
接口版本权限
-
接口限流权限
-
内网接口不对外开放
-
开放接口单独鉴权
遗漏 7:安全特权控制
企业安全合规必带:
-
三员管理(系统员、安全员、审计员)
-
最小权限原则
-
权限互斥
-
双角色登录
-
敏感操作二次认证
遗漏 8:权限缓存与刷新机制
实战高频痛点,必须设计:
-
权限本地缓存(Caffeine)
-
分布式缓存(Redis)
-
权限变更实时刷新
-
角色变更自动踢下线
-
避免每次请求查库
遗漏 9:异常权限场景处理
线上必出现,架构必须兜底:
-
无权限统一返回
-
越权访问拦截
-
非法 Token 拦截
-
会话过期自动跳转
-
黑名单 Token 拦截
-
密码暴力破解拦截
遗漏 10:权限审计日志(等保 / 合规必备)
漏了这个过不了等保三级:
-
登录日志
-
登出日志
-
权限变更日志
-
越权访问日志
-
敏感操作日志
-
数据导出日志
遗漏 11:第三方登录 & 统一身份认证(企业必用)
现在企业系统不可能只做账号密码登录:
-
OAuth2(微信、钉钉、企业微信)
-
OIDC 统一登录
-
CAS 单点登录
-
LDAP 企业域账号
-
扫码登录、短信登录
遗漏 12:前端权限完整闭环
后端架构必须配合前端,实战必须包含:
-
动态路由
-
按钮级指令
-
无权限页面隐藏
-
403 页面
-
权限同步刷新
遗漏 13:灰度权限 / 功能开关
大型项目必备:
-
按用户灰度
-
按角色灰度
-
按部门灰度
-
功能开关(不发布直接关闭模块)
遗漏 14:开放平台权限(OAuth2.0 / Client 模式)
如果给第三方提供接口,必须有:
-
应用鉴权(appId + appKey)
-
接口调用权限
-
调用频次控制
-
第三方应用权限范围(scope)
遗漏 15:安全防御体系(权限架构的底座)
权限不是独立的,必须和安全绑定:
-
防 SQL 注入
-
防 XSS
-
防 CSRF
-
防重放攻击
-
防水平越权
-
防垂直越权
-
接口签名
十一、学习路线(从入门到精通)
-
理解 RBAC 模型 + 表结构设计
-
学习 Spring Security 或 Sa-Token
-
实现登录、认证、接口权限
-
实现菜单 / 按钮权限
-
掌握 JWT + Redis
-
实现数据权限
-
微服务网关鉴权
-
安全加固与最佳实践
总结
-
Java 权限架构 = 认证 + 授权 + 权限模型 + 框架 + 分布式方案 + 安全
-
RBAC 是基础,数据权限是核心,微服务鉴权是进阶
-
企业首选:Sa-Token / Spring Security + RBAC + Redis + 网关统一鉴权
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)