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.
 
 
 
 
 

25 KiB

JWT认证机制

**本文引用的文件** - [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) - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [AuthProperties.java](file://crm-auth/src/main/java/com/crm/auth/config/AuthProperties.java) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.java) - [LoginParam.java](file://crm-auth/src/main/java/com/crm/auth/domain/param/LoginParam.java) - [LoginResultDTO.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/LoginResultDTO.java) - [UserInfoDTO.java](file://crm-auth/src/main/java/com/crm/auth/domain/dto/UserInfoDTO.java) - [AuthUser.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthUser.java) - [AuthIdentity.java](file://crm-auth/src/main/java/com/crm/auth/domain/entity/AuthIdentity.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) - [AuthUserMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/AuthUserMapper.java) - [AuthIdentityMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/AuthIdentityMapper.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) - [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java) - [RedisConfig.java](file://crm-base/src/main/java/com/crm/base/config/RedisConfig.java) - [SecurityUtils.java](file://crm-base/src/main/java/com/crm/base/security/SecurityUtils.java) - [LoginUser.java](file://crm-base/src/main/java/com/crm/base/security/LoginUser.java)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考量
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件围绕JWT认证机制,系统性解析令牌结构、签发流程、验证与刷新策略,重点说明JwtAuthenticationFilter的拦截与注入逻辑,以及TokenService的令牌管理能力。同时给出安全配置最佳实践(密钥管理、过期策略、跨域支持等),并提供常见问题排查方法与性能优化建议,帮助读者快速落地并稳定运行JWT鉴权体系。

项目结构

本项目采用多模块设计,认证相关代码集中在crm-auth模块,基础能力在crm-base模块提供。JWT认证的关键位置如下:

  • 安全配置与属性:SecurityConfig、AuthProperties
  • 过滤器与令牌服务:JwtAuthenticationFilter、TokenService
  • 登录接口与数据模型:AuthController、LoginParam、LoginResultDTO、UserInfoDTO
  • 用户与身份实体:AuthUser、AuthIdentity
  • 服务与持久化:IAuthService、AuthServiceImpl、AuthUserMapper、AuthIdentityMapper
  • 常量与配置:AuthConstants、application.yml
  • 跨域与缓存:CorsConfig、RedisConfig
  • 工具类:SecurityUtils、LoginUser
graph TB
subgraph "认证模块 crm-auth"
AC["AuthController"]
AP["AuthProperties"]
SC["SecurityConfig"]
JF["JwtAuthenticationFilter"]
TS["TokenService"]
IA["IAuthService"]
AS["AuthServiceImpl"]
AU["AuthUser"]
AI["AuthIdentity"]
AMU["AuthUserMapper"]
AMI["AuthIdentityMapper"]
Cst["AuthConstants"]
Yml["application.yml"]
end
subgraph "基础模块 crm-base"
CC["CorsConfig"]
RC["RedisConfig"]
SU["SecurityUtils"]
LU["LoginUser"]
end
AC --> TS
AC --> IA
IA --> AS
AS --> AMU
AS --> AMI
JF --> TS
SC --> JF
SC --> CC
TS --> RC
TS --> Cst
TS --> Yml
SU --> LU

图表来源

  • SecurityConfig.java
  • JwtAuthenticationFilter.java
  • TokenService.java
  • AuthController.java
  • AuthProperties.java
  • AuthServiceImpl.java
  • AuthUserMapper.java
  • AuthIdentityMapper.java
  • AuthConstants.java
  • application.yml
  • CorsConfig.java
  • RedisConfig.java
  • SecurityUtils.java
  • LoginUser.java

章节来源

  • SecurityConfig.java
  • JwtAuthenticationFilter.java
  • TokenService.java
  • AuthController.java
  • AuthProperties.java
  • AuthServiceImpl.java
  • AuthUserMapper.java
  • AuthIdentityMapper.java
  • AuthConstants.java
  • application.yml
  • CorsConfig.java
  • RedisConfig.java
  • SecurityUtils.java
  • LoginUser.java

核心组件

  • JwtAuthenticationFilter:请求级拦截器,负责从请求头提取JWT、校验签名与有效期、构建认证上下文并注入到安全上下文。
  • TokenService:令牌工厂与生命周期管理者,负责生成、解析、续期、撤销、黑名单管理等。
  • SecurityConfig:Spring Security配置,注册过滤器、设置放行路径、跨域与异常处理。
  • AuthController:对外暴露登录、注销、刷新等接口,调用服务层完成认证与令牌发放。
  • IAuthService/AuthServiceImpl:业务认证实现,校验用户名密码或第三方身份,组装用户信息。
  • 数据模型:LoginParam、LoginResultDTO、UserInfoDTO、AuthUser、AuthIdentity。
  • 配置与常量:AuthProperties、AuthConstants、application.yml、CorsConfig、RedisConfig。
  • 工具类:SecurityUtils、LoginUser用于获取当前登录用户与安全上下文操作。

章节来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • SecurityConfig.java
  • AuthController.java
  • IAuthService.java
  • AuthServiceImpl.java
  • LoginParam.java
  • LoginResultDTO.java
  • UserInfoDTO.java
  • AuthUser.java
  • AuthIdentity.java
  • AuthProperties.java
  • AuthConstants.java
  • application.yml
  • CorsConfig.java
  • RedisConfig.java
  • SecurityUtils.java
  • LoginUser.java

架构总览

JWT认证的整体流程包括:客户端发起登录,服务端校验凭证后签发JWT;后续请求携带JWT,过滤器解析并注入用户信息;业务方法通过工具类获取当前用户。令牌续期与撤销由TokenService统一管理,必要时结合Redis进行黑名单或会话控制。

sequenceDiagram
participant Client as "客户端"
participant Controller as "AuthController"
participant Service as "IAuthService/AuthServiceImpl"
participant Token as "TokenService"
participant Filter as "JwtAuthenticationFilter"
participant SecCfg as "SecurityConfig"
participant Redis as "Redis(可选)"
Note over Client,SecCfg : 登录阶段
Client->>Controller : POST /auth/login
Controller->>Service : 校验用户名/密码或第三方身份
Service-->>Controller : 用户信息与权限
Controller->>Token : 签发JWT(含用户ID、角色、权限等)
Token-->>Controller : 返回access_token/refresh_token
Controller-->>Client : 登录成功响应
Note over Client,Filter : 受保护资源访问
Client->>Filter : 携带Authorization : Bearer <token>
Filter->>Token : 解析并验证签名/过期/黑名单
Token-->>Filter : 解析后的用户信息
Filter->>SecCfg : 写入SecurityContext
Filter-->>Client : 放行至业务控制器
Note over Client,Token : 刷新令牌
Client->>Controller : POST /auth/refresh
Controller->>Token : 使用refresh_token换取新access_token
Token-->>Controller : 新令牌
Controller-->>Client : 刷新成功响应

图表来源

  • AuthController.java
  • IAuthService.java
  • AuthServiceImpl.java
  • TokenService.java
  • JwtAuthenticationFilter.java
  • SecurityConfig.java
  • RedisConfig.java

详细组件分析

JwtAuthenticationFilter工作原理

  • 请求拦截:在Spring Security过滤链中优先执行,读取Authorization头中的Bearer令牌。
  • 令牌解析:委托TokenService解析并校验签名、过期时间、黑名单状态。
  • 用户信息注入:将解析出的用户信息封装为认证对象,写入SecurityContext,供后续授权判断与业务使用。
  • 异常处理:对非法令牌、缺失令牌、解析失败等情况统一抛出异常或拒绝访问。
flowchart TD
Start(["进入过滤器"]) --> ReadHeader["读取Authorization头"]
ReadHeader --> HasToken{"是否存在Bearer令牌?"}
HasToken --> |否| PassThrough["跳过认证<br/>交由后续过滤器或放行规则"]
HasToken --> |是| Parse["调用TokenService解析令牌"]
Parse --> Valid{"是否有效且未过期?"}
Valid --> |否| Reject["拒绝访问(401/403)"]
Valid --> |是| BuildCtx["构建认证上下文并注入SecurityContext"]
BuildCtx --> Continue["继续过滤器链/放行至控制器"]
PassThrough --> End(["结束"])
Reject --> End
Continue --> End

图表来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • SecurityConfig.java

章节来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • SecurityConfig.java

TokenService令牌管理

  • 生成:根据用户信息生成JWT,包含必要声明(如用户ID、角色、权限、扩展信息等),设置过期时间。
  • 验证:校验签名、过期时间、黑名单状态;可结合Redis做在线会话或强制下线。
  • 续期:基于refresh_token签发新的access_token,支持滑动过期策略。
  • 撤销:将令牌加入黑名单或使refresh_token失效,支持批量撤销与按用户维度撤销。
  • 存储:可选择无状态(仅JWT)或有状态(Redis记录会话/黑名单)。
classDiagram
class TokenService {
+generateAccessToken(user) string
+generateRefreshToken(user) string
+parseAndValidate(token) UserInfo
+refreshAccessToken(refreshToken) string
+revoke(token) void
+isBlacklisted(token) bool
+extendExpiry(token) bool
}
class RedisConfig {
+redisTemplate
}
class AuthConstants {
+ACCESS_TOKEN_PREFIX
+REFRESH_TOKEN_PREFIX
+EXPIRE_ACCESS_SECONDS
+EXPIRE_REFRESH_SECONDS
}
TokenService --> RedisConfig : "可选 : 黑名单/会话"
TokenService --> AuthConstants : "读取令牌前缀与过期配置"

图表来源

  • TokenService.java
  • RedisConfig.java
  • AuthConstants.java

章节来源

  • TokenService.java
  • AuthConstants.java
  • RedisConfig.java

登录与令牌签发流程

  • 客户端提交登录参数(用户名/密码或第三方标识)。
  • 服务层校验凭证,查询用户与身份信息,组装用户上下文。
  • TokenService签发access_token与refresh_token,返回给客户端。
  • 客户端保存令牌并在后续请求中携带。
sequenceDiagram
participant Client as "客户端"
participant AC as "AuthController"
participant SA as "AuthServiceImpl"
participant TS as "TokenService"
Client->>AC : POST /auth/login(LoginParam)
AC->>SA : authenticate(LoginParam)
SA-->>AC : UserInfoDTO(用户信息+权限)
AC->>TS : generateAccessToken(UserInfoDTO)
TS-->>AC : access_token
AC->>TS : generateRefreshToken(UserInfoDTO)
TS-->>AC : refresh_token
AC-->>Client : LoginResultDTO{access_token, refresh_token}

图表来源

  • AuthController.java
  • AuthServiceImpl.java
  • TokenService.java
  • LoginParam.java
  • LoginResultDTO.java
  • UserInfoDTO.java

章节来源

  • AuthController.java
  • AuthServiceImpl.java
  • TokenService.java
  • LoginParam.java
  • LoginResultDTO.java
  • UserInfoDTO.java

用户信息注入与上下文使用

  • JwtAuthenticationFilter解析成功后,将用户信息封装为认证对象并写入SecurityContext。
  • 业务层通过SecurityUtils获取当前登录用户(LoginUser),避免重复解析JWT。
  • 权限与数据范围控制可在过滤器链之后进行,结合注解或拦截器实现。
sequenceDiagram
participant Filter as "JwtAuthenticationFilter"
participant TS as "TokenService"
participant SecCtx as "SecurityContext"
participant Utils as "SecurityUtils"
participant Biz as "业务控制器"
Filter->>TS : parseAndValidate(token)
TS-->>Filter : 用户信息
Filter->>SecCtx : 写入认证对象
Biz->>Utils : getCurrentUser()
Utils-->>Biz : LoginUser
Biz-->>Biz : 执行业务逻辑

图表来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • SecurityUtils.java
  • LoginUser.java

章节来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • SecurityUtils.java
  • LoginUser.java

刷新与撤销策略

  • 刷新:客户端使用refresh_token调用刷新接口,服务端校验通过后签发新的access_token,支持滑动过期。
  • 撤销:服务端可将access_token或refresh_token加入黑名单,或在Redis中删除会话键,强制下线。
  • 策略建议:短时效access_token配合长时效refresh_token,减少泄露风险;定期清理黑名单与过期会话。
flowchart TD
Start(["刷新入口"]) --> CheckRefresh["校验refresh_token有效性"]
CheckRefresh --> Valid{"是否有效?"}
Valid --> |否| Error["返回401/403"]
Valid --> |是| RevokeOld["撤销旧access_token(可选)"]
RevokeOld --> GenNew["签发新access_token"]
GenNew --> Return["返回新令牌"]
Error --> End(["结束"])
Return --> End

图表来源

  • TokenService.java
  • AuthController.java

章节来源

  • TokenService.java
  • AuthController.java

数据模型与实体关系

  • AuthUser:用户主表,包含账号、密码、状态等。
  • AuthIdentity:第三方身份关联,支持多种登录方式。
  • DTO与Param:登录参数、登录结果、用户信息传输对象。
erDiagram
AUTH_USER {
bigint id PK
string username UK
string password
int status
datetime created_at
datetime updated_at
}
AUTH_IDENTITY {
bigint id PK
bigint user_id FK
string identity_type
string identity_value
datetime created_at
}
AUTH_USER ||--o{ AUTH_IDENTITY : "拥有"

图表来源

  • AuthUser.java
  • AuthIdentity.java

章节来源

  • AuthUser.java
  • AuthIdentity.java

依赖关系分析

  • 过滤器依赖TokenService进行令牌解析与校验。
  • TokenService依赖RedisConfig(可选)与AuthConstants(令牌前缀与过期配置)。
  • 认证控制器依赖服务层完成凭证校验与用户信息组装。
  • 安全配置注册过滤器、设置放行路径与跨域策略。
graph LR
JF["JwtAuthenticationFilter"] --> TS["TokenService"]
TS --> RC["RedisConfig"]
TS --> ACst["AuthConstants"]
AC["AuthController"] --> TS
AC --> IA["IAuthService"]
IA --> AS["AuthServiceImpl"]
AS --> AMU["AuthUserMapper"]
AS --> AMI["AuthIdentityMapper"]
SC["SecurityConfig"] --> JF
SC --> CC["CorsConfig"]

图表来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • RedisConfig.java
  • AuthConstants.java
  • AuthController.java
  • IAuthService.java
  • AuthServiceImpl.java
  • AuthUserMapper.java
  • AuthIdentityMapper.java
  • SecurityConfig.java
  • CorsConfig.java

章节来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • AuthController.java
  • IAuthService.java
  • AuthServiceImpl.java
  • AuthUserMapper.java
  • AuthIdentityMapper.java
  • SecurityConfig.java
  • CorsConfig.java

性能考量

  • 令牌解析开销:尽量精简JWT载荷,避免过大payload导致序列化/反序列化开销。
  • Redis交互:黑名单与刷新令牌校验需尽量减少网络往返,合理设置超时与连接池。
  • 过滤器链顺序:确保JwtAuthenticationFilter尽早执行,减少无效请求进入业务层。
  • 缓存策略:用户信息、权限列表可缓存以减少数据库压力。
  • 并发与限流:登录与刷新接口应加限流与防重放措施。

[本节为通用指导,不直接分析具体文件]

故障排查指南

  • 401未认证:检查Authorization头格式是否正确、令牌是否过期、是否被拉黑。
  • 403禁止访问:确认用户权限与资源访问规则是否匹配。
  • 解析失败:核对签名密钥、算法配置、时区与时间同步问题。
  • 刷新失败:检查refresh_token是否有效、是否已被撤销或过期。
  • 跨域错误:确认CORS配置允许的来源、方法与头部。

章节来源

  • JwtAuthenticationFilter.java
  • TokenService.java
  • SecurityConfig.java
  • CorsConfig.java

结论

本方案以JwtAuthenticationFilter与TokenService为核心,实现了无状态与有状态相结合的JWT认证机制。通过合理的令牌结构与生命周期管理、严格的安全配置与跨域支持,能够满足企业级应用的高可用与高安全需求。建议在生产环境强化密钥管理、启用HTTPS、实施限流与审计,持续监控令牌使用与健康指标。

[本节为总结性内容,不直接分析具体文件]

附录

  • 安全配置最佳实践
    • 密钥管理:使用强随机密钥,定期轮换,生产环境通过环境变量或密钥管理服务注入。
    • 过期策略:access_token短时效(如15分钟),refresh_token较长时效(如7天),支持滑动过期。
    • 跨域支持:明确允许的源、方法与头部,避免使用通配符。
    • 黑名单与会话:结合Redis实现强制下线、设备管理与会话统计。
    • 日志与审计:记录登录、刷新、撤销事件,便于追踪与合规。

[本节为通用指导,不直接分析具体文件]