# 安全认证 **本文引用的文件** - [AuthProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java) - [JwtAuthFilter.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JwtAuthFilter.java) - [AuthController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java) - [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java) - [AuthenticationException.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/exception/AuthenticationException.java) - [JwtUtilsTests.java](file://fms-api/src/test/java/cn/g3soft/fmsapi/utils/JwtUtilsTests.java) ## 目录 1. [简介](#简介) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构总览](#架构总览) 5. [详细组件分析](#详细组件分析) 6. [依赖分析](#依赖分析) 7. [性能考虑](#性能考虑) 8. [故障排查指南](#故障排查指南) 9. [结论](#结论) 10. [附录](#附录) ## 简介 本文件面向FMS后端的安全认证子系统,聚焦基于JWT的无状态认证方案。文档围绕以下目标展开: - 解释JwtAuthFilter过滤器的工作流程与拦截策略 - 说明令牌生成、校验与刷新机制 - 阐述AuthProperties配置类与安全参数管理 - 描述JwtUtils工具类的核心能力(解析、用户信息提取、权限验证) - 给出过期处理、防重放攻击等安全考量与最佳实践 ## 项目结构 安全认证相关代码集中在fms-api模块中,采用分层组织: - 配置层:AuthProperties负责读取并绑定安全相关配置项 - 过滤层:JwtAuthFilter在请求进入控制器前进行鉴权 - 控制层:AuthController暴露登录、登出、刷新等接口 - 服务层:AuthService封装认证业务逻辑(如会话管理、权限加载) - 异常层:AuthenticationException统一认证失败异常 - 工具层:JwtUtils提供JWT编解码与校验能力(通过测试用例可见其使用方式) ```mermaid graph TB Client["客户端"] --> Filter["JwtAuthFilter
请求前置鉴权"] Filter --> Controller["AuthController
登录/刷新/登出"] Controller --> Service["AuthService
认证业务逻辑"] Service --> Utils["JwtUtils
令牌解析/校验"] Service --> Config["AuthProperties
安全参数配置"] Service --> DB["数据源/缓存
用户与权限"] ``` 图表来源 - [JwtAuthFilter.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JwtAuthFilter.java) - [AuthController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java) - [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java) - [AuthProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java) 章节来源 - [JwtAuthFilter.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JwtAuthFilter.java) - [AuthController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java) - [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java) - [AuthProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java) ## 核心组件 - JwtAuthFilter:在Servlet过滤器链中对每个请求进行JWT校验,决定是否放行或拒绝 - AuthController:对外暴露认证相关HTTP接口,接收登录凭证并返回令牌 - AuthService:实现认证核心流程,包括用户校验、权限装配、令牌签发与刷新 - AuthProperties:集中管理JWT密钥、过期时间、白名单路径等安全参数 - JwtUtils:提供令牌的生成、解析、签名校验与载荷提取 - AuthenticationException:统一抛出认证失败异常,便于全局异常处理 章节来源 - [JwtAuthFilter.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JwtAuthFilter.java) - [AuthController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java) - [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java) - [AuthProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java) - [AuthenticationException.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/exception/AuthenticationException.java) ## 架构总览 下图展示了从浏览器发起请求到服务端完成鉴权的整体流程,以及关键组件间的交互关系。 ```mermaid sequenceDiagram participant C as "客户端" participant F as "JwtAuthFilter" participant A as "AuthController" participant S as "AuthService" participant U as "JwtUtils" participant P as "AuthProperties" C->>F : "携带Authorization头发起请求" F->>F : "匹配白名单/忽略路径" alt "需要鉴权" F->>U : "解析并校验JWT" U-->>F : "有效载荷/错误" alt "令牌无效或过期" F-->>C : "401/403响应" else "令牌有效" F->>S : "加载用户上下文/权限" S-->>F : "上下文对象" F->>A : "放行至控制器" A-->>C : "业务响应" end else "白名单路径" F->>A : "直接放行" A-->>C : "业务响应" end ``` 图表来源 - [JwtAuthFilter.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JwtAuthFilter.java) - [AuthController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java) - [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java) - [AuthProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java) ## 详细组件分析 ### JwtAuthFilter 过滤器 职责与行为 - 拦截所有入站请求,判断是否命中白名单或静态资源 - 从请求头中提取JWT令牌并进行解析与签名校验 - 将解析出的用户信息与权限注入到当前请求上下文,供后续处理器使用 - 对未认证或权限不足请求返回标准错误码 关键点 - 白名单策略:允许匿名访问的路径(如登录、健康检查) - 令牌位置:通常从Authorization头获取Bearer Token - 错误处理:捕获解析异常并转换为统一的认证失败响应 ```mermaid flowchart TD Start(["进入过滤器"]) --> CheckPath["判断是否白名单/静态资源"] CheckPath --> |是| Pass["放行至控制器"] CheckPath --> |否| ExtractToken["提取Authorization头中的令牌"] ExtractToken --> Validate["调用JwtUtils校验令牌"] Validate --> Valid{"校验通过?"} Valid --> |否| Deny["返回401/403"] Valid --> |是| BuildCtx["构建用户上下文/权限"] BuildCtx --> Next["继续过滤器链/到达控制器"] ``` 图表来源 - [JwtAuthFilter.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JwtAuthFilter.java) 章节来源 - [JwtAuthFilter.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JwtAuthFilter.java) ### AuthController 控制器 职责与行为 - 提供登录接口:接收用户名/密码,委托AuthService完成认证并签发JWT - 提供刷新接口:支持基于旧令牌换取新令牌(可结合黑名单/滑动窗口) - 提供登出接口:使旧令牌失效(可选,取决于是否启用令牌黑名单) 典型交互 - 登录成功返回包含access_token与refresh_token的响应体 - 刷新时校验refresh_token有效性并颁发新的access_token - 登出时将当前token加入黑名单或标记为已注销 ```mermaid sequenceDiagram participant C as "客户端" participant AC as "AuthController" participant AS as "AuthService" participant JU as "JwtUtils" participant AP as "AuthProperties" C->>AC : "POST /login {username,password}" AC->>AS : "authenticate(username,password)" AS->>JU : "generateAccessToken(user, properties)" JU-->>AS : "access_token" AS-->>AC : "{access_token, refresh_token}" AC-->>C : "200 OK" C->>AC : "POST /refresh {refresh_token}" AC->>AS : "refresh(refresh_token)" AS->>JU : "validateAndGenerateNew(token, properties)" JU-->>AS : "new_access_token" AS-->>AC : "{access_token}" AC-->>C : "200 OK" ``` 图表来源 - [AuthController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java) - [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java) - [AuthProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java) 章节来源 - [AuthController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java) - [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java) ### AuthService 服务 职责与行为 - 认证主流程:校验用户身份、加载角色与权限、签发令牌 - 刷新流程:校验refresh_token、生成新的access_token - 会话管理:维护活跃会话列表、支持强制下线与并发控制 - 权限装配:将用户权限集合注入到上下文,供授权决策使用 注意 - 与数据库或缓存交互以获取用户与权限信息 - 与JwtUtils协作完成令牌生命周期管理 - 与AuthProperties配合读取密钥、过期时间等参数 章节来源 - [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java) ### AuthProperties 配置类 作用 - 集中管理JWT相关安全参数,如: - 签名密钥(secret/key) - access_token与refresh_token过期时间 - 白名单路径列表 - 是否启用黑名单/撤销机制 - 最大会话数、并发限制等 使用方式 - 通过配置文件(如application.yaml)注入属性 - 在过滤器与服务中读取配置,驱动鉴权与令牌策略 章节来源 - [AuthProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java) ### JwtUtils 工具类 核心功能 - 生成access_token与refresh_token - 解析并校验JWT签名与有效期 - 从载荷中提取用户标识、角色与权限 - 支持刷新令牌的重放防护(如一次性使用或短期有效) 测试覆盖 - JwtUtilsTests验证了令牌的生成、解析与基本校验逻辑 章节来源 - [JwtUtilsTests.java](file://fms-api/src/test/java/cn/g3soft/fmsapi/utils/JwtUtilsTests.java) ## 依赖分析 组件间耦合关系如下: - JwtAuthFilter依赖JwtUtils进行令牌校验,依赖AuthProperties决定白名单策略 - AuthController依赖AuthService完成认证业务 - AuthService依赖JwtUtils进行令牌签发与校验,依赖AuthProperties读取安全参数 - 所有组件通过统一的AuthenticationException对外暴露认证失败语义 ```mermaid graph LR Filter["JwtAuthFilter"] --> Utils["JwtUtils"] Filter --> Props["AuthProperties"] Controller["AuthController"] --> Service["AuthService"] Service --> Utils Service --> Props Service --> DB["用户/权限存储"] ``` 图表来源 - [JwtAuthFilter.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JwtAuthFilter.java) - [AuthController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java) - [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java) - [AuthProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java) 章节来源 - [JwtAuthFilter.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/JwtAuthFilter.java) - [AuthController.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/controller/AuthController.java) - [AuthService.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/service/AuthService.java) - [AuthProperties.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/config/AuthProperties.java) ## 性能考虑 - 令牌校验开销:尽量将高频校验逻辑(如签名验证)优化为本地计算;必要时引入缓存减少重复查询 - 会话管理:活跃会话表/缓存需设计合理的索引与淘汰策略,避免内存膨胀 - 刷新令牌:建议设置较短的access_token过期时间与较长的refresh_token周期,降低频繁刷新带来的压力 - 白名单与静态资源:尽早放行以减少过滤器链开销 - 并发控制:限制单用户并发会话数,防止资源滥用 ## 故障排查指南 常见问题与定位 - 401 未认证:检查Authorization头是否正确携带Bearer Token;确认白名单配置是否误拦截 - 403 权限不足:检查用户角色与权限是否已正确加载;确认接口是否需要特定权限 - 令牌过期:调整access_token过期时间或实现自动刷新;检查客户端是否在过期前刷新 - 刷新失败:检查refresh_token是否已被使用或撤销;确认黑名单机制是否生效 - 签名错误:核对AuthProperties中的密钥是否与签发端一致 定位步骤 - 查看过滤器日志:确认是否进入鉴权分支、令牌解析结果 - 检查服务层日志:确认用户与权限加载是否成功 - 复现最小用例:构造仅含必要字段的请求,逐步缩小问题范围 章节来源 - [AuthenticationException.java](file://fms-api/src/main/java/cn/g3soft/fmsapi/exception/AuthenticationException.java) ## 结论 本系统采用JWT无状态认证,结合过滤器前置鉴权与统一异常处理,实现了清晰的鉴权边界与可扩展的权限模型。通过AuthProperties集中管理安全参数,JwtUtils提供稳定的令牌处理能力,AuthService串联认证与会话管理。建议在部署时严格管理密钥、合理设置过期时间、启用刷新与黑名单机制,并结合监控与审计提升安全性与可观测性。 ## 附录 - 安全配置最佳实践 - 使用强随机密钥并定期轮换 - 区分access_token与refresh_token的过期策略 - 启用HTTPS传输,防止中间人攻击 - 记录登录与操作日志,便于审计与溯源 - 常见安全问题防护 - 防重放攻击:对敏感接口增加nonce/time-window校验或使用一次性refresh_token - 会话劫持:绑定设备指纹或IP段(谨慎使用),加强Cookie/Token存储安全 - 暴力破解:对登录接口实施限流与验证码 - 越权访问:在服务层进行细粒度权限校验,不仅依赖前端控制