这是企业级 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 标准登录认证完整流程(生产级)
  1. 客户端提交账号密码/验证码等身份凭证

  2. 服务端校验账号状态(是否禁用、是否删除)

  3. 密码加密比对(BCrypt 匹配校验)

  4. 校验通过,加载用户基础信息、租户信息、部门信息

  5. 生成唯一登录 Token,存入 Redis(设置过期时间、绑定设备)

  6. 缓存用户角色、权限数据,避免重复查库

  7. 返回 Token、用户信息、权限标识给前端

  8. 记录登录日志,完成认证闭环

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 标准授权执行流程(生产级)
  1. 客户端携带有效 Token 发起业务请求

  2. 拦截器校验 Token 有效性,完成身份认证

  3. 从 Redis 缓存中读取当前用户的角色列表、权限码列表、数据范围

  4. 触发接口授权校验(角色/权限码匹配)

  5. 触发数据权限切面,拼接数据过滤 SQL

  6. 触发字段权限拦截,完成字段显隐、脱敏处理

  7. 校验全部通过,执行业务逻辑;任意环节失败,抛出 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 生产级完整防护逻辑(双权限闭环)

一次请求 = 先防垂直越权,再防水平越权,双重校验杜绝所有越权风险。

  1. 拦截器校验 Token,完成认证

  2. 垂直权限校验:判断用户是否拥有当前接口权限,无权限直接拦截

  3. 水平权限校验:根据用户身份拼接数据过滤 SQL

  4. 查询数据、脱敏字段、返回结果

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 执行流程
  1. 用户登录系统

  2. 系统根据 userId 查询「用户-权限关联表」

  3. 加载当前用户的全部权限集合

  4. 请求接口时,直接匹配用户所持权限码,完成鉴权

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 标准执行流程(生产级)
  1. 用户登录系统,完成身份认证,生成有效Token

  2. 根据用户ID查询 sys_user_role,获取用户绑定的所有角色

  3. 根据角色ID批量查询 sys_role_permission,汇总用户所有权限码

  4. 将用户角色、权限列表、数据范围缓存至Redis,提升后续鉴权性能

  5. 用户请求接口时,拦截器/注解校验当前用户是否拥有对应角色或权限码

  6. 校验通过则放行,校验失败抛出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 核心执行流程(生产级)
  1. 用户登录认证成功,加载用户全部属性信息(部门、职级、角色等)

  2. 用户发起业务请求,拦截器捕获当前用户、资源、环境、操作四大属性

  3. 系统加载预设的ABAC权限规则表达式

  4. 动态匹配属性条件,校验是否满足放行规则

  5. 匹配通过则放行,匹配失败直接抛出403无权限异常

  6. 支持权限规则缓存,提升高并发鉴权性能

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 执行流程(网关级全局鉴权)
  1. 客户端发起请求,统一进入微服务网关(Gateway)

  2. 网关完成Token校验、身份解析,获取请求全量上下文参数

  3. 加载系统预设的所有PBAC权限策略(已缓存、支持动态刷新)

  4. 逐条匹配策略规则,根据优先级筛选最终生效策略

  5. 执行策略动作(放行/拦截/二次认证)

  6. 放行请求转发至后端微服务,拦截则直接返回403权限异常

  7. 记录策略执行日志,用于权限审计、安全溯源

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. 登录认证核心流程(生成合法会话)

核心目标:校验用户身份合法性,生成可管控的会话令牌,缓存用户权限数据,完成身份确权,为后续所有鉴权提供依据。

  1. 接收前端凭证:客户端提交账号密码、验证码、动态令牌等身份凭证,同时携带设备信息、IP地址;

  2. 基础合法性校验:校验账号是否存在、是否禁用/注销、验证码是否有效、登录频次是否合规(防暴力破解);

  3. 密码安全校验:采用BCrypt算法比对密码,禁止明文、MD5校验,杜绝密码泄露风险;

  4. 加载用户权限数据:查询数据库,获取用户基础信息、绑定角色、权限码集合、数据权限范围、部门信息;

  5. 生成会话令牌:企业主流采用 UUID随机Token(可控可作废),微服务场景可搭配JWT承载基础信息;

  6. Redis会话缓存落地:将Token、用户信息、角色、权限、数据范围存入Redis,设置过期时间、绑定设备IP,支持续期、踢下线;

  7. 权限预热缓存:单独缓存用户权限集合,避免每次请求查库,大幅提升鉴权性能;

  8. 返回会话信息:将Token、用户信息、可访问菜单、权限标识返回前端,前端存储Token用于后续请求鉴权;

  9. 登录日志归档:记录登录时间、IP、设备、状态,用于安全审计、异常溯源,满足等保合规。


3. 接口请求鉴权核心流程(核心校验闭环)

核心目标:对已登录用户的每一次业务请求,完成身份校验、功能权限校验、数据权限隔离、字段脱敏四层管控,杜绝垂直、水平越权。

  1. 全局请求拦截:所有接口请求优先经过网关(微服务)/自定义拦截器(单体),白名单接口(登录、验证码、注册)直接放行;

  2. Token有效性校验:从请求头解析Token,校验Token是否存在、是否过期、是否被手动作废(黑名单校验);

  3. 解析用户上下文:从Redis缓存读取用户信息,存入ThreadLocal线程上下文,实现全局线程隔离,避免多请求串参;

  4. 第一层:登录鉴权:校验用户是否处于有效登录状态,匿名用户直接拦截,返回403未登录异常;

  5. 第二层:角色鉴权:根据接口注解配置,校验用户是否拥有指定角色(如admin、manager),适配岗位层级管控;

  6. 第三层:功能权限鉴权:校验用户是否拥有当前接口的权限码(如sys:user:list),拦截无权限的功能操作,防垂直越权;

  7. 第四层:数据权限过滤:通过AOP切面+MyBatis拦截器,根据用户数据范围(本人/本部门/全部)自动拼接SQL过滤条件,防水平越权;

  8. 第五层:字段权限脱敏:根据用户权限等级,自动隐藏敏感字段、脱敏手机号/身份证/金额,实现字段级精细化管控;

  9. 业务逻辑执行:所有权限校验通过后,执行接口核心业务逻辑;

  10. 请求收尾清理:请求结束后清空ThreadLocal上下文,防止内存泄漏;

  11. 操作日志记录:记录用户操作行为、请求参数、操作结果,用于安全审计与问题排查。


4. 权限注销流程(会话销毁闭环)

核心目标:主动销毁会话,回收权限,防止账号被盗用,完成权限生命周期闭环。

  1. 接收登出请求:客户端发起登出操作,携带当前登录Token;

  2. 校验Token合法性:确认Token有效、用户登录状态正常;

  3. 销毁Redis会话:删除当前Token对应的Redis会话缓存、用户权限缓存,立即失效登录状态;

  4. 清空线程上下文:手动清除ThreadLocal存储的用户信息,彻底释放资源;

  5. 记录登出日志:记录登出时间、IP、设备信息,完善安全审计链路;

  6. 返回登出结果:通知前端清空本地Token、用户信息,完成登出闭环。

拓展:强制踢下线流程(后台管理员操作):后台作废指定用户Token缓存 → 加入黑名单 → 用户后续请求直接拦截 → 强制跳转登录页,实现权限实时回收。


5. 权限缓存联动流程(性能核心)

企业级权限核心优化逻辑,解决高频查库性能瓶颈,同时保证权限实时生效。

  1. 登录缓存预热:用户登录成功,一次性缓存角色、权限、数据范围至Redis,有效期同步Token过期时间;

  2. 日常鉴权走缓存:所有请求鉴权优先读取缓存,无需查询数据库,接口性能大幅提升;

  3. 权限变更实时刷新:后台修改用户角色、权限、数据范围时,自动清空对应用户权限缓存;

  4. 缓存自愈机制:缓存失效/清空后,用户下次请求自动重新加载权限并缓存,无需手动干预。


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 完整登录认证流程
  1. 客户端提交账号密码,完成身份校验;

  2. 认证成功后,服务端创建 HttpSession 会话,写入用户信息、权限数据;

  3. 容器生成唯一 SessionId,自动写入响应 Cookie 返回前端;

  4. 前端浏览器自动存储 Cookie,后续每次请求自动携带;

  5. 服务端拦截器根据请求中的 SessionId 匹配会话,校验登录状态;

  6. 登出时手动销毁 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 核心认证原理
  1. 用户登录成功,服务端根据用户信息、过期时间、秘钥生成合规JWT令牌;

  2. 服务端不存储JWT及用户会话信息,直接将令牌返回给前端;

  3. 前端存储JWT(LocalStorage/Header),后续所有请求在请求头携带令牌;

  4. 服务端接收请求后,解析JWT、校验签名合法性、校验过期时间;

  5. 校验通过后提取用户身份、权限信息,完成鉴权,无需查库校验会话;

  6. 校验失败(篡改、过期、非法秘钥)直接拦截,返回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 标准生产级执行流程
  1. 登录确权:用户账号密码校验通过后,清空该用户历史会话(可选多端互踢),生成全局唯一随机Token。

  2. Redis缓存落地:以 login:token:{token} 为Key,将用户权限、设备信息、会话属性序列化存入Redis,设置动态过期时间(默认2小时,支持续期)。

  3. 返回客户端凭证:仅将Token字符串返回前端,前端存储在LocalStorage,后续所有请求统一在请求头 Authorization 携带。

  4. 请求鉴权校验:拦截器解析请求头Token,查询Redis判断会话是否存在、是否过期、是否被拉黑。

  5. 加载用户上下文:Redis读取用户角色、权限、数据范围,存入ThreadLocal,供全局接口、AOP权限切面使用。

  6. 会话续期机制:用户活跃时自动刷新Redis过期时间,实现「活跃永不过期、闲置自动登出」的企业级体验。

  7. 登出/踢下线销毁:主动登出或后台踢下线时,直接删除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解析与合法性校验 → 黑名单/过期校验 → 用户信息封装请求头 → 路由转发下游服务 → 业务服务二次精细化鉴权 → 执行业务逻辑

  1. 第一层:网关粗校验(全局拦截):只校验「是否合法登录用户」,拦截未登录、Token失效、拉黑、非法篡改的请求,不做精细角色、权限码校验,保证网关转发高性能。

  2. 第二层:服务细校验(业务兜底):下游业务服务接收网关透传的用户上下文,完成角色权限、功能权限、数据权限、字段权限的精细化校验,杜绝权限越权。

1.3 核心实现原理(Gateway过滤器机制)

基于Gateway全局过滤器 GlobalFilter + 有序过滤器链实现统一鉴权,通过自定义过滤器优先级,保证鉴权逻辑优先于路由、业务逻辑执行,核心执行顺序:

  1. 优先级最高:跨域、限流、非法参数拦截

  2. 次优先级:白名单接口匹配放行

  3. 核心流程:Token解析、会话校验、黑名单校验

  4. 后置流程:封装用户上下文、路由转发、日志记录

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 权限中心整体架构分层

采用分层架构设计,职责清晰、解耦彻底,适配高并发、高可用分布式场景:

  1. 接入层(网关对接):接收网关透传的用户请求信息,承接全局统一认证后的精细化权限预处理,对接网关黑名单、会话管控体系。

  2. 接口服务层:对外暴露HTTP/Feign RPC接口,供网关、各业务服务调用,包含身份校验、权限查询、数据范围获取、用户信息查询等核心接口。

  3. 核心业务层:实现角色管理、权限分配、数据规则配置、用户关联、租户隔离、权限缓存刷新等核心业务逻辑。

  4. 缓存层:基于Redis实现权限、角色、会话数据缓存,支撑秒级鉴权、权限实时刷新、多端会话管控。

  5. 数据持久层:统一维护权限体系数据库表,持久化用户、角色、权限、关联关系、数据规则等核心数据。

2.3 权限中心核心对外接口(生产通用)

所有业务服务通过Feign远程调用权限中心接口,无需重复开发权限逻辑,核心接口如下:

  • 身份校验接口:校验Token有效性、用户登录状态、账号是否禁用/注销。

  • 用户信息查询接口:根据用户ID获取用户基础信息、部门、岗位、租户信息。

  • 角色权限查询接口:批量获取用户绑定角色、拥有的全部权限码、可访问菜单列表。

  • 数据范围查询接口:获取用户对应的数据权限范围(本人/本部门/全部/自定义)。

  • 权限校验接口:传入用户ID+权限码/角色标识,批量校验是否拥有对应权限。

  • 会话管控接口:实现踢下线、批量注销会话、清空用户权限缓存等操作。

2.4 权限中心+微服务完整交互流程
  1. 用户登录阶段:用户提交登录请求 → 网关拦截校验 → 转发至权限中心 → 权限中心校验账号密码、生成Token、缓存权限数据、返回登录结果。

  2. 业务请求阶段:用户携带Token请求业务接口 → 网关统一粗校验(登录态、黑名单) → 透传用户信息至业务服务。

  3. 精细化鉴权阶段:业务服务通过Feign调用权限中心接口 → 校验角色/权限码、获取数据范围 → 完成功能权限+数据权限双重校验。

  4. 权限变更阶段:管理员在权限中心修改角色、权限、数据规则 → 自动清空对应用户缓存 → 下游服务下次请求自动加载最新权限。

  5. 登出管控阶段:用户登出/后台踢下线 → 权限中心删除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 菜单层级规范(企业统一标准)

所有后台系统菜单统一遵循「三级层级架构」,规范清晰、适配性强:

  1. 一级:目录(D):仅做分类聚合,无具体页面,如「系统管理」「用户中心」

  2. 二级:菜单(M):具体业务页面,可路由访问,如「用户管理」「角色管理」

  3. 三级:按钮(B):页面内操作按钮,无独立路由,归属对应菜单,关联按钮权限码

1.3 完整权限联动流程(生产闭环)

基于RBAC模型,实现「角色绑定菜单→用户继承角色菜单权限」的完整链路:

  1. 资源配置阶段:管理员在权限中心录入所有目录、菜单、按钮资源,绑定对应权限码,完成系统资源登记

  2. 角色授权阶段:给指定角色勾选可访问的菜单/目录,建立「角色-菜单」关联关系

  3. 用户赋权阶段:用户绑定对应角色,自动继承该角色所有菜单权限

  4. 登录加载阶段:用户登录成功后,后端根据用户ID查询绑定角色,汇总所有有权限的菜单数据,过滤禁用、隐藏资源

  5. 前端渲染阶段:前端接收后端返回的菜单树,动态生成侧边栏菜单,同时动态注册路由,拦截无权限路由访问

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 接口权限完整校验流程(生产闭环)
  1. 客户端携带 Token 发起接口请求,网关完成统一登录态粗校验,放行合法请求

  2. 请求进入业务服务,拦截器捕获请求,解析当前请求 URL、接口方法

  3. 获取当前登录用户的权限码缓存列表(从 ThreadLocal/Redis 获取,无需重复查库)

  4. 匹配接口绑定的权限码,校验用户是否拥有对应访问权限

  5. 权限校验通过,执行业务逻辑;校验失败,统一捕获异常,返回 403 无权限提示

  6. 记录接口访问日志、越权访问日志,用于安全审计

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:addsys:role:editsys:role:deletesys:role:assign(分配权限)

  • 部门模块:sys:dept:addsys:dept:editsys: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 按钮权限完整联动流程(生产闭环)
  1. 管理员在权限中心配置角色对应的页面按钮权限,绑定对应权限码。

  2. 用户登录系统,后端加载用户角色对应的所有按钮、菜单权限码,缓存并返回前端。

  3. 前端页面加载时,通过全局权限指令遍历所有按钮,匹配用户权限码。

  4. 有权限则正常展示按钮,无权限则移除/禁用按钮,优化页面交互。

  5. 用户点击按钮发起请求,后端接口权限注解二次校验,杜绝前端权限绕过漏洞。

  6. 后台修改按钮权限后,清空用户权限缓存,用户刷新页面即可生效最新权限。

3.6 特殊业务场景落地方案
  • 多按钮批量权限管控:同一页面多个按钮权限独立配置,支持单个角色拥有部分按钮权限,精准差异化管控。

  • 按钮权限动态切换:结合业务状态联动权限,如单据审批完成后,自动隐藏「审核、驳回」按钮,无需后端改权限配置。

  • 超级管理员权限兜底:超级管理员默认拥有所有按钮权限,自动跳过权限校验,所有功能按钮全部可见可操作。

  • 弹窗按钮权限管控:弹窗内操作按钮同样绑定权限指令,统一适配弹窗场景权限管控,无权限弹窗按钮自动隐藏。

3.7 生产落地避坑核心要点
  • 严禁前端单一权限管控:按钮权限仅做前端交互优化,必须配套后端接口鉴权,防止用户通过接口调试工具绕过前端按钮限制,直接调用接口越权操作。

  • 权限码严格统一:按钮权限码、菜单权限码、接口权限码必须一一对应,避免出现「按钮隐藏但接口可访问、按钮显示但接口无权限」的适配bug。

  • 禁止硬编码权限:不允许在前端代码写死角色判断、权限判断,所有权限由后端动态配置,保证权限灵活可改。

  • 权限缓存及时刷新:角色按钮权限变更后,必须清空前端本地权限缓存+后端Redis权限缓存,避免用户长期缓存旧权限。

  • 空权限兜底处理:用户无任何按钮权限时,页面自动隐藏所有操作入口,避免出现空白按钮、无效功能入口。

3.8 面试高频终极考点
  • 按钮权限的实现原理? 基于RBAC模型,按钮绑定标准权限码,用户登录后前端获取权限码列表,通过自定义指令动态控制按钮显隐,后端接口鉴权兜底。

  • 为什么按钮权限不能替代接口权限? 前端按钮控制仅为展示层面,可通过代码篡改、接口调试工具绕过,无法保障安全,后端接口鉴权是唯一安全底线。

  • 按钮权限、菜单权限、接口权限的关联关系? 三者共用同一套权限码规范,菜单管控页面路由、按钮管控页面交互、接口管控后台访问,层层联动、闭环防护。

  • 权限更新后为什么需要刷新缓存? 用户权限码会缓存至前端本地和后端Redis,不刷新缓存会导致权限变更无法实时生效,出现权限滞后问题。

  • 多角色用户按钮权限如何叠加? 自动合并多个角色的按钮权限码,取并集,拥有任意角色对应权限即可展示对应按钮。

权限码规范(企业通用)

模块:功能:操作

例:sys:user:listsys:user:addsys:user:editsys:user:deletesys:user:export


八、数据权限实现(高级核心、企业重难点)

核心定位:数据权限是企业权限体系最核心、最难落地、面试必考的高级能力,专门解决水平越权漏洞。功能权限控制「能不能操作功能」,数据权限控制「操作时能看到哪些数据」,实现同接口、同角色、不同用户,查询数据结果差异化,是政务、金融、OA、SaaS系统的刚需能力。

核心本质:基于当前登录用户的身份(用户ID、部门ID、角色数据范围),无侵入自动拼接SQL过滤条件,从数据库层面拦截非法数据,彻底杜绝水平越权。

核心落地架构:自定义数据权限注解 + AOP切面预处理 + MyBatis拦截器动态SQL拼接 + ThreadLocal上下文传递,全程零业务代码侵入,适配所有业务接口。

1、核心实现原理与整体流程

  1. 注解标记接口:业务查询接口添加 @DataScope 自定义注解,标识该接口需要开启数据权限过滤

  2. AOP切面解析权限:接口请求进入切面,获取当前登录用户ID、部门ID、角色配置的数据权限范围

  3. 封装过滤参数:根据数据范围规则,生成对应的SQL过滤条件(如 dept_id = 1001、create_by = 10001),存入ThreadLocal上下文

  4. MyBatis拦截器拼接SQL:拦截所有SELECT查询SQL,自动拼接上下文的过滤条件,实现数据过滤

  5. 清空上下文:接口执行完毕,清空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 种权限,缺一不可:

  1. 菜单权限(能看到哪些菜单)

  2. 按钮权限(能点哪些按钮)

  3. 接口权限(能调用哪些 API)

  4. 数据权限(能看到哪些数据)

  5. 字段权限(能看到哪些字段:手机号、金额脱敏)

✅ 字段权限是 90% 教程会漏的,但金融 / ERP/OA 必用


遗漏 3:权限的生命周期管理

架构不是只做 “鉴权”,还要管权限从创建到销毁:

plaintext

申请 → 分配 → 启用 → 变更 → 回收 → 审计 → 过期

包含:

  • 临时权限

  • 自动过期权限

  • 权限申请 / 审批流

  • 权限回收机制


遗漏 4:超级管理员与权限隔离

实战必须有:

  1. 平台超级管理员

  2. 租户管理员(SaaS)

  3. 部门管理员

  4. 普通角色

  5. 权限不可越级分配(关键安全规则)


遗漏 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

  • 防重放攻击

  • 防水平越权

  • 防垂直越权

  • 接口签名

十一、学习路线(从入门到精通)

  1. 理解 RBAC 模型 + 表结构设计

  2. 学习 Spring Security 或 Sa-Token

  3. 实现登录、认证、接口权限

  4. 实现菜单 / 按钮权限

  5. 掌握 JWT + Redis

  6. 实现数据权限

  7. 微服务网关鉴权

  8. 安全加固与最佳实践


总结

  • Java 权限架构 = 认证 + 授权 + 权限模型 + 框架 + 分布式方案 + 安全

  • RBAC 是基础,数据权限是核心,微服务鉴权是进阶

  • 企业首选:Sa-Token / Spring Security + RBAC + Redis + 网关统一鉴权

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐