You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

36 KiB

认证核心机制

**本文引用的文件** - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [JwtAuthenticationFilter.java](file://crm-auth/src/main/java/com/crm/auth/security/JwtAuthenticationFilter.java) - [TokenService.java](file://crm-auth/src/main/java/com/crm/auth/security/TokenService.java) - [AuthLoginUser.java](file://crm-auth/src/main/java/com/crm/auth/security/AuthLoginUser.java) - [PermissionResolver.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolver.java) - [PermissionResolverImpl.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionResolverImpl.java) - [PermissionGrant.java](file://crm-auth/src/main/java/com/crm/auth/security/PermissionGrant.java) - [DataVisibility.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibility.java) - [DataVisibilityContext.java](file://crm-base/src/main/java/com/crm/base/security/DataVisibilityContext.java) - [DataScopeLevel.java](file://crm-base/src/main/java/com/crm/base/security/DataScopeLevel.java) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.java) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [IAuthService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthService.java) - [AuthServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthServiceImpl.java) - [AuthIdentity.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthIdentity.java) - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [IAuthIdentityService.java](file://crm-auth/src/main/java/com/crm/auth/service/IAuthIdentityService.java) - [AuthIdentityServiceImpl.java](file://crm-auth/src/main/java/com/crm/auth/service/impl/AuthIdentityServiceImpl.java) - [BaseServiceImpl.java](file://crm-base/src/main/java/com/crm/base/service/impl/BaseServiceImpl.java) - [IBaseService.java](file://crm-base/src/main/java/com/crm/base/service/IBaseService.java) - [DataScopeInterceptor.java](file://crm-auth/src/main/java/com/crm/auth/security/DataScopeInterceptor.java) - [SecurityExceptionHandlers.java](file://crm-auth/src/main/java/com/crm/auth/security/SecurityExceptionHandlers.java) - [AuthConstants.java](file://crm-auth/src/main/java/com/crm/auth/constant/AuthConstants.java) - [application.yml](file://crm-auth/src/main/resources/application.yml)

更新摘要

变更内容

  • 重构认证流程:引入统一的locateUser()方法,简化用户定位逻辑
  • 改进身份管理:增强孤儿身份处理机制,支持身份绑定重定向
  • 优化登录流程:分离事务内外操作,提升性能和数据一致性
  • 完善第三方登录:支持跨平台身份合一和自动注册功能

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录:配置示例与最佳实践

简介

本技术文档聚焦于认证核心机制,围绕JWT令牌的生成、验证与刷新、安全过滤器链(请求拦截、用户身份解析、权限校验)、以及会话管理与并发控制等高级特性进行系统化说明。文档同时给出完整的配置要点与故障排查建议,帮助读者快速理解并落地实现。

更新 本次更新重点介绍了重构后的认证流程,包括统一的locateUser()方法、改进的身份管理机制和孤儿身份处理功能,显著提升了系统的可维护性和用户体验。

项目结构

认证相关代码主要位于 crm-auth 模块中,关键目录与职责如下:

  • config:安全配置类,定义过滤器链、跨域、授权策略等
  • security:安全核心组件,包括JWT过滤器、令牌服务、登录用户上下文、权限解析器、数据范围拦截器、异常处理器
  • controller:认证入口控制器,提供登录、登出、刷新等接口
  • service:认证业务逻辑,封装用户校验、角色权限加载、第三方登录等
  • domain:领域模型,包括用户实体、身份绑定、DTO等
  • constant:常量定义,如令牌前缀、过期时间、错误码等
  • resources:应用配置文件,包含JWT、Redis、安全策略等参数
graph TB
subgraph "crm-auth"
C["config/SecurityConfig"] --> F["security/JwtAuthenticationFilter"]
F --> T["security/TokenService"]
F --> U["security/AuthLoginUser"]
F --> PR["security/PermissionResolver"]
PR --> PRI["security/PermissionResolverImpl"]
PRI --> PG["security/PermissionGrant"]
F --> DSI["security/DataScopeInterceptor"]
F --> SEH["security/SecurityExceptionHandlers"]
Ctrl["controller/AuthController"] --> Svc["service/IAuthService + impl/AuthServiceImpl"]
Svc --> DB["持久层(用户/角色/菜单)"]
T --> Redis["缓存(Redis)"]
Svc --> AIS["service/impl/AuthIdentityServiceImpl"]
AIS --> AI["domain/entity/AuthIdentity"]
end
subgraph "crm-base"
DV["security/DataVisibility"]
DVC["security/DataVisibilityContext"]
DSL["security/DataScopeLevel"]
BS["service/impl/BaseServiceImpl"]
end
PRI --> DV
PRI --> DVC
PRI --> DSL
BS --> IBS["service/IBaseService"]

图表来源

  • SecurityConfig.java
  • JwtAuthenticationFilter.java
  • TokenService.java
  • AuthLoginUser.java
  • PermissionResolver.java
  • PermissionResolverImpl.java
  • PermissionGrant.java
  • DataVisibility.java
  • DataVisibilityContext.java
  • DataScopeLevel.java
  • DataScopeInterceptor.java
  • SecurityExceptionHandlers.java
  • AuthController.java
  • IAuthService.java
  • AuthServiceImpl.java
  • AuthIdentity.java
  • AuthUser.java
  • IAuthIdentityService.java
  • AuthIdentityServiceImpl.java
  • BaseServiceImpl.java
  • IBaseService.java

核心组件

  • 安全配置(SecurityConfig):注册过滤器链、白名单路径、跨域、授权规则等
  • JWT过滤器(JwtAuthenticationFilter):从请求头提取令牌、校验签名、构建认证上下文
  • 令牌服务(TokenService):负责JWT签发、解析、刷新、黑名单/在线会话管理
  • 登录用户(AuthLoginUser):承载当前用户身份、角色、权限、数据范围等上下文信息
  • 权限解析器(PermissionResolver):实现fail-closed安全策略,一次解析用户全部授权信息
  • 权限授予对象(PermissionGrant):不可变的价值对象,封装数据可见性、权限码并集、角色编码
  • 数据可见性(DataVisibility):表示用户可访问的数据范围,支持多种档位
  • 数据可见性上下文(DataVisibilityContext):ThreadLocal存储请求级数据范围
  • 身份管理服务(IAuthIdentityService):管理三方身份绑定和孤儿身份处理
  • 统一用户定位(locateUser):重构后的用户定位方法,支持身份绑定和手机号匹配
  • 数据范围拦截器(DataScopeInterceptor):基于注解或上下文注入SQL数据范围条件
  • 异常处理器(SecurityExceptionHandlers):统一处理认证失败、权限不足、令牌异常等
  • 认证控制器(AuthController):暴露登录、登出、刷新、获取用户信息等接口
  • 认证服务(IAuthService/AuthServiceImpl):封装用户校验、角色权限加载、第三方登录流程

架构总览

下图展示了认证核心机制的整体架构与交互关系,涵盖请求进入、JWT校验、用户上下文构建、权限校验与数据范围过滤的关键路径。

sequenceDiagram
participant Client as "客户端"
participant Filter as "JwtAuthenticationFilter"
participant TokenSvc as "TokenService"
participant PermRes as "PermissionResolver"
participant SecCtx as "安全上下文(AuthLoginUser)"
participant DSInt as "DataScopeInterceptor"
participant Ctrl as "AuthController/业务控制器"
Client->>Filter : "携带Authorization : Bearer <token>"
Filter->>TokenSvc : "解析并校验JWT签名/过期"
TokenSvc-->>Filter : "返回有效载荷(用户ID/角色/权限)"
Filter->>PermRes : "解析用户权限(一次算清)"
PermRes-->>Filter : "返回PermissionGrant(可见性+权限码+角色)"
Filter->>SecCtx : "构建认证上下文(含数据范围)"
Filter->>DSInt : "执行数据范围拦截"
DSInt-->>Filter : "注入SQL数据范围条件"
Filter->>Ctrl : "放行到目标方法"
Ctrl-->>Client : "返回业务结果"

图表来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • PermissionResolver.java
  • PermissionResolverImpl.java
  • PermissionGrant.java
  • DataVisibility.java
  • DataVisibilityContext.java
  • DataScopeInterceptor.java
  • AuthController.java

详细组件分析

重构的认证流程与统一用户定位

更新 认证流程经过重构,引入了统一的locateUser()方法,简化了用户定位逻辑并增强了身份管理能力。

  • 统一用户定位:locateUser()方法整合了身份绑定查询和手机号匹配逻辑,避免重复代码
  • 事务分离:将DB操作与HTTP调用分离,提升性能和数据一致性
  • 孤儿身份处理:自动检测并修复指向已删除用户的身份绑定记录
  • 跨平台身份合一:支持通过手机号关联不同平台的同一用户
flowchart TD
A["登录请求"] --> B["authCode换取三方用户信息"]
B --> C["事务外组织准入预校验"]
C --> D{"本地已有匹配用户?"}
D --> |是| E["直接复用用户"]
D --> |否| F["查询身份绑定记录"]
F --> G{"存在身份绑定?"}
G --> |是| H["检查用户是否存在"]
H --> |存在| I["返回已存在用户"]
H --> |不存在| J["警告并继续注册"]
G --> |否| K["按手机号匹配用户"]
K --> L{"找到用户?"}
L --> |是| M["返回匹配用户"]
L --> |否| N["首登自动注册新用户"]
N --> O["绑定三方身份"]
O --> P["处理孤儿身份重定向"]
P --> Q["返回新用户"]
E --> R["更新最后登录时间"]
I --> R
M --> R
J --> N
R --> S["签发JWT令牌"]
S --> T["返回登录结果"]

图表来源

  • AuthServiceImpl.java
  • AuthIdentityServiceImpl.java
  • IAuthIdentityService.java

章节来源

  • AuthServiceImpl.java:64-93
  • AuthServiceImpl.java:117-139
  • AuthServiceImpl.java:149-165

身份管理与孤儿身份处理

更新 新增完善的身份管理机制,支持孤儿身份的自动检测和修复。

  • 身份绑定表设计:AuthIdentity实体支持多平台身份绑定,唯一约束确保身份唯一性
  • 孤儿身份检测:当身份绑定的用户被物理删除时,自动重定向到新创建的用户
  • 身份绑定策略:优先使用已绑定身份,其次按手机号匹配,最后自动注册新用户
  • 审计日志:记录孤儿身份重定向操作,便于问题追踪
classDiagram
class AuthIdentity {
+userId : Long
+identityType : String
+unionId : String
+openId : String
+mobile : String
}
class AuthServiceImpl {
+login(type, authCode)
+doLoginInTx(type, thirdUser)
+resolveUser(type, thirdUser)
+locateUser(type, thirdUser, identity)
+registerNewUser(thirdUser)
}
class IAuthIdentityService {
<<interface>>
+getByTypeAndUnionId(type, unionId)
+bind(userId, type, info)
}
class AuthIdentityServiceImpl {
+getByTypeAndUnionId(type, unionId)
+bind(userId, type, info)
}
AuthServiceImpl --> IAuthIdentityService : "依赖"
AuthIdentityServiceImpl --> IAuthIdentityService : "实现"
AuthIdentityServiceImpl --> AuthIdentity : "操作"

图表来源

  • AuthIdentity.java
  • AuthServiceImpl.java
  • IAuthIdentityService.java
  • AuthIdentityServiceImpl.java

章节来源

  • AuthIdentity.java:15-53
  • AuthIdentityServiceImpl.java:15-34
  • AuthServiceImpl.java:127-138

JWT令牌生命周期与刷新机制

  • 签发:登录成功后由TokenService生成访问令牌与可选的刷新令牌,写入响应头或响应体;必要时将令牌元数据(如设备指纹、IP、过期时间)存入Redis用于在线会话管理
  • 校验:JwtAuthenticationFilter在每次请求时提取Authorization头,调用TokenService校验签名、有效期、是否被拉黑;通过后构建AuthLoginUser上下文
  • 刷新:当访问令牌即将过期或已过期时,使用刷新令牌换取新的访问令牌;刷新过程中可校验刷新令牌有效性、设备一致性、并发限制等
  • 注销:服务端维护令牌黑名单或撤销在线会话,确保立即失效
flowchart TD
Start(["开始"]) --> Extract["从请求头提取令牌"]
Extract --> Validate{"令牌有效?"}
Validate --> |否| HandleInvalid["抛出认证异常/返回未授权"]
Validate --> |是| BuildCtx["构建AuthLoginUser上下文"]
BuildCtx --> PermResolve["权限解析(PermissionResolver)"]
PermResolve --> Scope["数据范围拦截器注入SQL条件"]
Scope --> Pass["放行至控制器"]
Pass --> End(["结束"])
HandleInvalid --> End

图表来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • AuthLoginUser.java
  • PermissionResolver.java
  • DataScopeInterceptor.java

章节来源

  • TokenService.java
  • JwtAuthenticationFilter.java
  • AuthController.java
  • AuthConstants.java

安全过滤器链与请求拦截

  • 过滤器链顺序:CORS -> TraceId -> JwtAuthenticationFilter -> DataScopeInterceptor -> 业务控制器
  • 白名单:静态资源、健康检查、部分公开接口可跳过JWT校验
  • 鉴权:在过滤器或控制器层面根据角色/权限决定放行与否
  • 异常:统一由SecurityExceptionHandlers捕获并返回标准错误格式
sequenceDiagram
participant Client as "客户端"
participant Filter as "JwtAuthenticationFilter"
participant PermRes as "PermissionResolver"
participant DSInt as "DataScopeInterceptor"
participant Handler as "SecurityExceptionHandlers"
participant Ctrl as "业务控制器"
Client->>Filter : "HTTP请求"
Filter->>Filter : "白名单判断/跨域处理"
Filter->>Filter : "JWT解析与校验"
Filter->>PermRes : "权限解析(一次算清)"
PermRes-->>Filter : "返回PermissionGrant"
Filter->>DSInt : "数据范围拦截"
DSInt-->>Filter : "注入数据范围"
Filter->>Ctrl : "放行"
Ctrl-->>Client : "成功响应"
Note over Filter,Handler : "若发生认证/权限异常,交由异常处理器统一处理"

图表来源

  • SecurityConfig.java
  • JwtAuthenticationFilter.java
  • PermissionResolver.java
  • DataScopeInterceptor.java
  • SecurityExceptionHandlers.java

章节来源

  • SecurityConfig.java
  • JwtAuthenticationFilter.java
  • DataScopeInterceptor.java
  • SecurityExceptionHandlers.java

AuthLoginUser设计模式与会话管理

  • 设计模式:采用"登录用户上下文"模式,将用户标识、角色、权限、数据范围等信息聚合为单一对象,便于在过滤器、拦截器、服务层与控制器间传递
  • 会话管理:结合Redis存储在线会话元数据(如设备指纹、IP、最后活跃时间),支持单点登录、强制下线、并发登录控制
  • 数据可见性:通过数据范围上下文(部门、角色、自定义范围)动态注入SQL条件,实现行级数据隔离
classDiagram
class AuthLoginUser {
+用户ID
+用户名
+手机号
+头像
+构造(用户信息)
}
class TokenService {
+签发JWT()
+解析JWT()
+刷新令牌()
+加入黑名单()
+查询在线会话()
}
class PermissionResolver {
<<interface>>
+resolve(userId)
+visibleMenuTree(userId)
}
class PermissionResolverImpl {
+resolve(userId)
+visibleMenuTree(userId)
-authorizedMenus(roleIds)
}
class PermissionGrant {
+visibility : DataVisibility
+permCodes : Set~String~
+roleCodes : Set~String~
+asAuthorities()
}
class DataVisibility {
+userId : Long
+primaryDeptId : Long
+deptIds : Long[]
+level : DataScopeLevel
+expandedDeptIds : Long[]
+visibilityScope()
+dataOwnership()
}
class JwtAuthenticationFilter {
+doFilter(request, response)
-解析令牌()
-构建上下文()
}
class DataScopeInterceptor {
+preHandle(request, response, handler)
-注入数据范围()
}
JwtAuthenticationFilter --> TokenService : "校验/解析"
JwtAuthenticationFilter --> PermissionResolver : "权限解析"
PermissionResolverImpl --> PermissionGrant : "创建"
PermissionResolverImpl --> DataVisibility : "构建"
DataScopeInterceptor --> DataVisibility : "读取"

图表来源

  • AuthLoginUser.java
  • TokenService.java
  • PermissionResolver.java
  • PermissionResolverImpl.java
  • PermissionGrant.java
  • DataVisibility.java
  • JwtAuthenticationFilter.java
  • DataScopeInterceptor.java

章节来源

  • AuthLoginUser.java
  • TokenService.java
  • PermissionResolver.java
  • PermissionResolverImpl.java
  • PermissionGrant.java
  • DataVisibility.java
  • JwtAuthenticationFilter.java
  • DataScopeInterceptor.java

权限解析架构与Fail-Closed安全策略

  • PermissionResolver接口:定义权限解析的核心方法,包括用户权限解析和菜单树构建
  • PermissionResolverImpl实现:实现"用户→角色→授权→资源"的查询链,支持数据可见性计算、权限码并集、角色编码归一化
  • PermissionGrant价值对象:不可变的授权事实集合,包含数据可见性、权限码并集、角色编码
  • DataVisibility数据可见性:表示用户可访问的数据范围,支持SELF、DEPT、DEPT_AND_CHILDREN、ALL四种档位
  • DataVisibilityContext上下文:ThreadLocal存储请求级数据范围,确保线程安全
flowchart TD
A["用户ID"] --> B["PermissionResolver.resolve()"]
B --> C["查询用户角色"]
C --> D["计算数据可见性档位"]
D --> E["构建DataVisibility"]
C --> F["查询角色授权菜单"]
F --> G["过滤按钮类型权限"]
G --> H["去重权限码并集"]
C --> I["收集角色编码"]
E --> J["创建PermissionGrant"]
H --> J
I --> J
J --> K["Spring Security Authorities"]

图表来源

  • PermissionResolver.java
  • PermissionResolverImpl.java
  • PermissionGrant.java
  • DataVisibility.java
  • DataVisibilityContext.java

章节来源

  • PermissionResolver.java
  • PermissionResolverImpl.java
  • PermissionGrant.java
  • DataVisibility.java
  • DataVisibilityContext.java
  • DataScopeLevel.java

认证业务流程(登录、刷新、登出)

  • 登录:AuthController接收登录参数,调用IAuthService/AuthServiceImpl进行用户校验、角色权限加载,成功后由TokenService签发JWT并返回
  • 刷新:客户端携带刷新令牌请求刷新接口,服务端校验后签发新访问令牌
  • 登出:服务端将令牌加入黑名单或移除在线会话,使旧令牌立即失效
sequenceDiagram
participant Client as "客户端"
participant Ctrl as "AuthController"
participant Svc as "IAuthService/AuthServiceImpl"
participant Token as "TokenService"
participant PermRes as "PermissionResolver"
Client->>Ctrl : "POST /auth/login"
Ctrl->>Svc : "校验用户/加载角色权限"
Svc-->>Ctrl : "返回用户信息"
Ctrl->>Token : "签发JWT(访问/刷新)"
Token-->>Ctrl : "返回令牌"
Ctrl-->>Client : "登录成功响应"
Client->>Ctrl : "POST /auth/refresh"
Ctrl->>Token : "校验刷新令牌并签发新访问令牌"
Token-->>Ctrl : "返回新令牌"
Ctrl-->>Client : "刷新成功响应"
Client->>Ctrl : "POST /auth/logout"
Ctrl->>Token : "加入黑名单/移除在线会话"
Token-->>Ctrl : "操作结果"
Ctrl-->>Client : "登出成功响应"
Note over PermRes : "每次请求时由JWT过滤器自动解析权限"

图表来源

  • AuthController.java
  • IAuthService.java
  • AuthServiceImpl.java
  • TokenService.java
  • PermissionResolver.java

章节来源

  • AuthController.java
  • IAuthService.java
  • AuthServiceImpl.java
  • TokenService.java

依赖关系分析

  • 组件内聚与耦合:
    • JwtAuthenticationFilter依赖TokenService与AuthLoginUser,低耦合高内聚
    • PermissionResolverImpl依赖多个Mapper和缓存,实现复杂的权限解析逻辑
    • PermissionGrant是不可变对象,避免状态污染
    • DataScopeInterceptor依赖AuthLoginUser的数据范围字段,避免侵入业务逻辑
    • SecurityConfig集中管理过滤器链与白名单,降低分散配置风险
    • AuthServiceImpl依赖IAuthIdentityService进行身份管理,支持孤儿身份处理
  • 外部依赖:
    • Redis用于在线会话与令牌黑名单管理
    • MyBatis/数据库用于用户、角色、菜单等基础数据
  • 潜在循环依赖:
    • 通过接口解耦(IAuthService与其实现类),避免直接循环引用
graph LR
SC["SecurityConfig"] --> JF["JwtAuthenticationFilter"]
JF --> TS["TokenService"]
JF --> ALU["AuthLoginUser"]
JF --> PR["PermissionResolver"]
PR --> PRI["PermissionResolverImpl"]
PRI --> PG["PermissionGrant"]
PRI --> DV["DataVisibility"]
PRI --> DVC["DataVisibilityContext"]
JF --> DSI["DataScopeInterceptor"]
DSI --> ALU
AC["AuthController"] --> IA["IAuthService"]
IA --> AIS["AuthServiceImpl"]
AIS --> AISvc["IAuthIdentityService"]
AISvc --> AISvcImpl["AuthIdentityServiceImpl"]
TS --> Redis["Redis"]

图表来源

  • SecurityConfig.java
  • JwtAuthenticationFilter.java
  • TokenService.java
  • AuthLoginUser.java
  • PermissionResolver.java
  • PermissionResolverImpl.java
  • PermissionGrant.java
  • DataVisibility.java
  • DataVisibilityContext.java
  • DataScopeInterceptor.java
  • AuthController.java
  • IAuthService.java
  • AuthServiceImpl.java
  • IAuthIdentityService.java
  • AuthIdentityServiceImpl.java

性能考虑

  • JWT无状态校验:减少数据库查询,提升吞吐;但需配合Redis做黑名单与在线会话管理
  • 令牌刷新策略:合理设置访问令牌短时效、刷新令牌长时效,降低频繁鉴权开销
  • 权限解析优化:PermissionResolverImpl在一次解析中完成所有授权信息查询,避免多次数据库访问
  • 数据范围优化:在拦截器阶段注入SQL条件,避免在业务层重复计算
  • 缓存热点:用户角色与权限可缓存至Redis,缩短鉴权路径
  • 并发控制:基于设备指纹与IP限制同一用户并发会话数,防止资源滥用
  • 不可变对象:PermissionGrant和DataVisibility使用不可变设计,避免同步开销
  • 事务优化:将HTTP调用移出事务,避免长时间占用数据库连接
  • 身份查询优化:一次性查询身份绑定记录,避免重复数据库访问

故障排查指南

  • 常见错误类型:
    • 令牌缺失或格式错误:检查Authorization头与Bearer前缀
    • 签名无效或已过期:核对密钥配置与系统时钟同步
    • 权限不足:确认用户角色与接口权限映射
    • 数据范围异常:检查数据范围上下文是否正确注入
    • 权限解析失败:检查PermissionResolverImpl中的数据库连接和查询逻辑
    • 身份绑定异常:检查AuthIdentity表的唯一约束和数据完整性
  • 定位步骤:
    • 查看JwtAuthenticationFilter日志,确认令牌解析与校验过程
    • 检查TokenService的黑名单与在线会话状态
    • 确认SecurityConfig白名单与跨域配置
    • 核查DataScopeInterceptor的数据范围注入逻辑
    • 检查PermissionResolverImpl的权限解析流程和数据库查询
    • 查看AuthServiceImpl中的孤儿身份处理日志
  • 恢复措施:
    • 清理黑名单或重置在线会话
    • 重新签发令牌并更新客户端缓存
    • 修正权限映射或数据范围配置
    • 修复权限解析器的数据库连接和查询逻辑
    • 手动修复孤儿身份绑定记录

章节来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • SecurityConfig.java
  • DataScopeInterceptor.java
  • SecurityExceptionHandlers.java
  • PermissionResolverImpl.java
  • AuthServiceImpl.java

结论

本认证核心机制以JWT为核心,结合过滤器链与数据范围拦截,实现了高效、可扩展且安全的认证与授权体系。通过TokenService与会话管理,支持令牌刷新、黑名单、并发控制等高级特性;AuthLoginUser作为统一上下文,简化了跨层身份传递。

更新 重构后的认证流程通过统一的locateUser()方法和完善的身份管理机制,显著提升了系统的可维护性和用户体验。孤儿身份处理功能确保了数据一致性和系统稳定性。新的权限解析架构引入了PermissionResolver接口和PermissionResolverImpl实现,采用fail-closed安全策略确保安全性。PermissionGrant不可变对象提供了线程安全的授权事实封装,DataVisibility和DataVisibilityContext实现了请求级的数据范围管理。这些改进显著提升了系统的可维护性和安全性。

合理的配置与监控能有效保障系统的稳定性与安全性。

附录:配置示例与最佳实践

  • JWT配置要点:
    • 密钥长度与算法选择(建议使用强随机密钥与RS256/HS512)
    • 访问令牌与刷新令牌过期时间(短效访问+长效刷新)
    • 令牌前缀与头部名称(如Authorization: Bearer)
  • 安全策略:
    • 白名单最小化,仅开放必要接口
    • 跨域严格限定来源与方法
    • 统一异常处理与错误码规范
    • 权限解析采用fail-closed策略,确保解析失败即拒绝请求
  • 会话与并发:
    • 基于Redis存储在线会话,支持设备指纹与IP绑定
    • 限制同一用户并发会话数,防止账号共享
  • 监控与审计:
    • 记录登录、刷新、登出事件
    • 统计令牌校验失败率与超时情况
    • 定期清理过期会话与黑名单
    • 监控权限解析性能和数据库查询效率
    • 监控身份绑定操作和孤儿身份处理日志
  • 权限解析最佳实践:
    • 合理使用DataScopeLevel档位,避免过度放宽数据可见性
    • 利用PermissionGrant的asAuthorities()方法统一处理权限校验
    • 通过DataVisibilityContext确保线程安全的数据范围传递
    • 定期审查权限配置,确保最小权限原则
  • 身份管理最佳实践
    • 确保AuthIdentity表的唯一约束正确配置
    • 定期检查孤儿身份记录并及时修复
    • 合理设置手机号匹配的优先级和策略
    • 记录所有身份绑定操作的审计日志

章节来源

  • application.yml
  • AuthConstants.java
  • SecurityConfig.java
  • PermissionResolver.java
  • PermissionResolverImpl.java
  • PermissionGrant.java
  • DataVisibility.java
  • DataVisibilityContext.java
  • AuthIdentity.java
  • AuthServiceImpl.java