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.
23 KiB
23 KiB
安全配置
**本文引用的文件** - [SecurityConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/SecurityConfig.java) - [AuthController.java](file://crm-auth/src/main/java/com/crm/auth/controller/AuthController.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) - [PermissionConfig.java](file://crm-auth/src/main/java/com/crm/auth/config/PermissionConfig.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) - [CorsConfig.java](file://crm-base/src/main/java/com/crm/base/config/CorsConfig.java) - [GlobalExceptionHandlerAdvice.java](file://crm-base/src/main/java/com/crm/base/advice/GlobalExceptionHandlerAdvice.java) - [TraceIdFilter.java](file://crm-base/src/main/java/com/crm/base/filter/TraceIdFilter.java) - [DingTalkAuthClient.java](file://crm-auth/src/main/java/com/crm/auth/service/client/DingTalkAuthClient.java) - [ThirdPartyAuthClientFactory.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyAuthClientFactory.java) - [ThirdPartyUserInfo.java](file://crm-auth/src/main/java/com/crm/auth/service/client/ThirdPartyUserInfo.java) - [AuthService.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) - [SysMenuMapper.java](file://crm-auth/src/main/java/com/crm/auth/mapper/SysMenuMapper.java) - [application.yml](file://crm-app/src/main/resources/application.yml) - [application.yml](file://crm-auth/src/main/resources/application.yml)目录
简介
本文件面向安全配置与鉴权体系,覆盖JWT认证、用户权限、跨域、过滤器链、第三方登录集成、密码加密、会话管理、CSRF防护、安全审计日志、异常处理与安全漏洞防护策略。文档以代码级为依据,结合流程图与类图帮助读者快速理解并落地实施。
项目结构
本项目采用多模块结构,安全相关能力集中在 crm-auth(认证与授权)与 crm-base(通用基础能力)两个模块:
- crm-auth:负责认证控制器、JWT过滤器、令牌服务、权限配置、数据范围拦截器、第三方登录客户端等。
- crm-base:提供全局异常处理、CORS跨域、追踪ID过滤器、通用安全工具类等。
graph TB
subgraph "应用入口"
APP["应用启动<br/>application.yml"]
end
subgraph "认证与授权(crm-auth)"
SEC_CFG["SecurityConfig<br/>安全配置"]
AUTH_CTRL["AuthController<br/>登录/登出/刷新"]
JWT_FILTER["JwtAuthenticationFilter<br/>JWT过滤器"]
TOKEN_SVC["TokenService<br/>令牌生成/校验"]
PERM_CFG["PermissionConfig<br/>权限规则"]
DATA_SCOPE_INT["DataScopeInterceptor<br/>数据范围拦截"]
EXC_HANDLERS["SecurityExceptionHandlers<br/>安全异常处理"]
DINGTALK["DingTalkAuthClient<br/>钉钉登录"]
TP_FACTORY["ThirdPartyAuthClientFactory<br/>第三方工厂"]
TP_INFO["ThirdPartyUserInfo<br/>第三方用户信息"]
end
subgraph "基础能力(crm-base)"
CORS["CorsConfig<br/>跨域配置"]
GLOBAL_EXC["GlobalExceptionHandlerAdvice<br/>全局异常"]
TRACE["TraceIdFilter<br/>链路追踪"]
end
APP --> SEC_CFG
SEC_CFG --> JWT_FILTER
SEC_CFG --> PERM_CFG
AUTH_CTRL --> TOKEN_SVC
AUTH_CTRL --> DINGTALK
DINGTALK --> TP_FACTORY
TP_FACTORY --> TP_INFO
SEC_CFG --> DATA_SCOPE_INT
SEC_CFG --> EXC_HANDLERS
SEC_CFG --> CORS
SEC_CFG --> TRACE
图表来源
- SecurityConfig.java
- AuthController.java
- JwtAuthenticationFilter.java
- TokenService.java
- PermissionConfig.java
- DataScopeInterceptor.java
- SecurityExceptionHandlers.java
- CorsConfig.java
- TraceIdFilter.java
- DingTalkAuthClient.java
- ThirdPartyAuthClientFactory.java
- ThirdPartyUserInfo.java
章节来源
- application.yml
- application.yml
核心组件
- 安全配置与过滤器链:通过统一安全配置装配JWT过滤器、跨域、异常处理器、数据范围拦截器等,形成请求进入业务前的完整安全链。
- 令牌服务:负责JWT令牌的签发、解析、刷新与黑名单/过期策略(如使用缓存)。
- 认证控制器:封装登录、登出、刷新令牌、第三方登录回调等接口。
- 权限配置:定义URL级别的访问控制、角色/权限映射与数据范围策略。
- 第三方登录:抽象第三方认证客户端与工厂,支持扩展更多平台。
- 基础安全能力:全局异常处理、跨域、链路追踪等。
章节来源
- SecurityConfig.java
- TokenService.java
- AuthController.java
- PermissionConfig.java
- DingTalkAuthClient.java
- ThirdPartyAuthClientFactory.java
- CorsConfig.java
- GlobalExceptionHandlerAdvice.java
- TraceIdFilter.java
架构总览
下图展示一次“用户名+密码”登录的端到端流程,涵盖过滤器链、令牌服务、用户服务与权限加载。
sequenceDiagram
participant Client as "客户端"
participant Filter as "JwtAuthenticationFilter"
participant Controller as "AuthController"
participant TokenSvc as "TokenService"
participant AuthSrv as "IAuthService"
participant UserMapper as "AuthUserMapper"
participant MenuMapper as "SysMenuMapper"
Client->>Filter : "POST /auth/login"
Filter-->>Controller : "放行到控制器"
Controller->>AuthSrv : "验证用户名/密码"
AuthSrv->>UserMapper : "查询用户与状态"
UserMapper-->>AuthSrv : "用户实体"
AuthSrv-->>Controller : "认证成功"
Controller->>TokenSvc : "签发JWT(含角色/权限)"
TokenSvc-->>Controller : "返回令牌"
Controller-->>Client : "登录成功响应"
Note over Filter,Controller : "后续请求携带Authorization头<br/>由过滤器完成鉴权与上下文注入"
图表来源
- AuthController.java
- JwtAuthenticationFilter.java
- TokenService.java
- IAuthService.java
- AuthUserMapper.java
- SysMenuMapper.java
详细组件分析
JWT认证与令牌服务
- 令牌生成:在认证成功后,根据用户主体信息(含角色、权限)生成JWT,设置有效期与必要声明。
- 令牌校验:过滤器从请求头提取令牌,解析并写入安全上下文,供后续鉴权使用。
- 令牌刷新:提供刷新接口,基于旧令牌签发新令牌,可配合黑名单或Redis实现主动失效。
- 安全建议:
- 使用强随机密钥与合适的算法;避免将敏感信息放入令牌载荷。
- 合理设置过期时间,结合刷新机制平衡体验与安全。
- 对敏感操作增加二次确认或短期令牌。
classDiagram
class TokenService {
+签发令牌(用户信息)
+解析令牌()
+刷新令牌(旧令牌)
+校验令牌有效性()
}
class JwtAuthenticationFilter {
+doFilter(请求, 响应, 过滤器链)
-解析Authorization头()
-写入安全上下文()
}
class AuthLoginUser {
+用户标识
+角色集合
+权限集合
+是否有效()
}
TokenService <.. JwtAuthenticationFilter : "解析/校验"
JwtAuthenticationFilter --> AuthLoginUser : "构建上下文"
图表来源
- TokenService.java
- JwtAuthenticationFilter.java
- AuthLoginUser.java
章节来源
- TokenService.java
- JwtAuthenticationFilter.java
- AuthLoginUser.java
用户登录流程
- 输入校验:控制器接收登录参数并进行基础校验。
- 身份验证:调用认证服务校验用户名/密码及账户状态。
- 权限加载:成功后加载用户角色与菜单权限,写入令牌载荷。
- 响应输出:返回令牌及相关用户信息。
flowchart TD
Start(["开始"]) --> Validate["参数校验"]
Validate --> Valid{"校验通过?"}
Valid --> |否| Error["返回参数错误"]
Valid --> |是| CheckPwd["校验密码与状态"]
CheckPwd --> PwdOk{"密码正确且可用?"}
PwdOk --> |否| AuthFail["返回认证失败"]
PwdOk --> |是| LoadPerm["加载角色与权限"]
LoadPerm --> GenToken["生成JWT"]
GenToken --> ReturnResp["返回登录结果"]
ReturnResp --> End(["结束"])
AuthFail --> End
Error --> End
图表来源
- AuthController.java
- IAuthService.java
- AuthServiceImpl.java
- AuthUserMapper.java
- SysMenuMapper.java
章节来源
- AuthController.java
- IAuthService.java
- AuthServiceImpl.java
- AuthUserMapper.java
- SysMenuMapper.java
权限与数据范围拦截
- URL级权限:通过权限配置定义白名单与受保护路径,结合角色/权限进行拦截。
- 数据范围:通过拦截器注入数据可见性上下文,影响查询SQL的数据范围过滤。
- 最佳实践:
- 最小权限原则,默认拒绝未授权访问。
- 将静态资源与公开接口加入白名单,减少不必要的鉴权开销。
- 数据范围按租户/部门维度隔离,避免越权访问。
classDiagram
class PermissionConfig {
+配置白名单
+配置受保护路径
+角色/权限映射
}
class DataScopeInterceptor {
+preHandle(请求, 响应, 处理器)
-读取用户数据范围
-注入可见性上下文
}
PermissionConfig <.. DataScopeInterceptor : "读取策略"
图表来源
- PermissionConfig.java
- DataScopeInterceptor.java
章节来源
- PermissionConfig.java
- DataScopeInterceptor.java
跨域与安全过滤器链
- 跨域配置:统一允许的来源、方法与头部,限制暴露头与凭据策略。
- 过滤器链顺序:追踪ID过滤器 -> 跨域处理 -> JWT过滤器 -> 权限拦截 -> 业务控制器。
- 建议:
- 生产环境严格限制允许的源与方法。
- 开启必要的请求体大小限制与超时配置。
sequenceDiagram
participant Client as "客户端"
participant Trace as "TraceIdFilter"
participant CORS as "CorsConfig"
participant JWT as "JwtAuthenticationFilter"
participant Perm as "PermissionConfig"
participant Ctrl as "AuthController"
Client->>Trace : "HTTP请求"
Trace-->>CORS : "设置追踪ID"
CORS-->>JWT : "跨域预检/实际请求"
JWT-->>Perm : "鉴权检查"
Perm-->>Ctrl : "放行至控制器"
Ctrl-->>Client : "响应"
图表来源
- TraceIdFilter.java
- CorsConfig.java
- JwtAuthenticationFilter.java
- PermissionConfig.java
- AuthController.java
章节来源
- CorsConfig.java
- TraceIdFilter.java
- JwtAuthenticationFilter.java
- PermissionConfig.java
第三方登录集成
- 抽象客户端:定义统一的第三方认证客户端接口与用户信息模型。
- 工厂模式:根据平台类型创建对应客户端实例,便于扩展新平台。
- 典型流程:前端跳转第三方授权 -> 回调服务端 -> 获取第三方用户信息 -> 绑定本地用户 -> 签发JWT。
classDiagram
class ThirdPartyAuthClientFactory {
+创建客户端(平台类型)
}
class DingTalkAuthClient {
+获取授权码
+换取AccessToken
+拉取用户信息()
}
class ThirdPartyUserInfo {
+第三方用户标识
+昵称/头像
+邮箱/手机号
}
ThirdPartyAuthClientFactory --> DingTalkAuthClient : "创建实例"
DingTalkAuthClient --> ThirdPartyUserInfo : "返回用户信息"
图表来源
- ThirdPartyAuthClientFactory.java
- DingTalkAuthClient.java
- ThirdPartyUserInfo.java
章节来源
- ThirdPartyAuthClientFactory.java
- DingTalkAuthClient.java
- ThirdPartyUserInfo.java
安全异常处理与审计日志
- 全局异常:统一捕获业务异常、权限异常、资源不存在等,返回标准化响应。
- 安全异常:针对认证失败、令牌无效、越权访问等给出明确但不过度泄露信息的提示。
- 审计日志:记录关键安全事件(登录成功/失败、权限拒绝、第三方登录回调),包含追踪ID与IP。
flowchart TD
A["异常发生"] --> B{"异常类型"}
B --> |业务异常| C["业务异常处理器"]
B --> |权限异常| D["权限异常处理器"]
B --> |系统异常| E["系统异常处理器"]
C --> F["记录审计日志"]
D --> F
E --> F
F --> G["返回统一错误响应"]
图表来源
- GlobalExceptionHandlerAdvice.java
- SecurityExceptionHandlers.java
- TraceIdFilter.java
章节来源
- GlobalExceptionHandlerAdvice.java
- SecurityExceptionHandlers.java
- TraceIdFilter.java
依赖关系分析
- 控制器依赖服务层,服务层依赖Mapper进行数据访问。
- 安全过滤器依赖令牌服务与安全上下文对象。
- 权限配置与数据范围拦截器共同决定访问控制与数据可见性。
- 第三方登录通过工厂动态选择客户端,降低耦合。
graph LR
AuthCtrl["AuthController"] --> IAuthSrv["IAuthService"]
IAuthSrv --> AuthUserMapper["AuthUserMapper"]
IAuthSrv --> SysMenuMapper["SysMenuMapper"]
JwtFilter["JwtAuthenticationFilter"] --> TokenSvc["TokenService"]
JwtFilter --> AuthLoginUser["AuthLoginUser"]
PermCfg["PermissionConfig"] --> DataScopeInt["DataScopeInterceptor"]
TPFactory["ThirdPartyAuthClientFactory"] --> DingTalk["DingTalkAuthClient"]
DingTalk --> TPInfo["ThirdPartyUserInfo"]
图表来源
- AuthController.java
- IAuthService.java
- AuthUserMapper.java
- SysMenuMapper.java
- JwtAuthenticationFilter.java
- TokenService.java
- AuthLoginUser.java
- PermissionConfig.java
- DataScopeInterceptor.java
- ThirdPartyAuthClientFactory.java
- DingTalkAuthClient.java
- ThirdPartyUserInfo.java
章节来源
- AuthController.java
- IAuthService.java
- JwtAuthenticationFilter.java
- TokenService.java
- PermissionConfig.java
- DataScopeInterceptor.java
- ThirdPartyAuthClientFactory.java
- DingTalkAuthClient.java
- ThirdPartyUserInfo.java
性能考量
- 令牌解析与校验应尽可能轻量,必要时引入缓存以减少重复计算。
- 权限与菜单加载可缓存热点数据,降低数据库压力。
- 跨域预检请求较多时,合理设置预检缓存时间。
- 审计日志异步落盘,避免阻塞主流程。
- 连接池与线程池参数需根据压测调优。
[本节为通用指导,不直接分析具体文件]
故障排查指南
- 登录失败:检查用户名/密码、账户状态、第三方回调参数是否正确。
- 令牌无效:检查Authorization头格式、令牌是否过期或被吊销。
- 权限拒绝:核对角色/权限映射与路径白名单配置。
- 跨域错误:检查允许的源、方法、头部与凭据策略。
- 审计定位:通过追踪ID关联日志,定位请求全链路。
章节来源
- SecurityExceptionHandlers.java
- GlobalExceptionHandlerAdvice.java
- TraceIdFilter.java
结论
本项目的安全体系以JWT为核心,结合过滤器链、权限配置与数据范围拦截,实现了完整的认证与授权闭环。通过第三方登录工厂化设计,具备良好的可扩展性。配合全局异常处理与审计日志,提升了系统的可观测性与可维护性。建议在生产环境中持续优化令牌策略、权限缓存与审计性能,确保安全性与性能兼顾。
[本节为总结性内容,不直接分析具体文件]
附录
- 安全策略配置要点:
- 最小权限原则与默认拒绝。
- 严格的跨域与CORS策略。
- 合理的令牌生命周期与刷新机制。
- 敏感操作二次确认与短期令牌。
- 密码加密规则:
- 使用强哈希算法与盐值,禁止明文存储。
- 定期轮换密钥与升级算法。
- 会话管理与CSRF防护:
- 无状态JWT为主,必要时结合黑名单或Redis。
- 若启用Cookie会话,需开启CSRF防护并限制SameSite。
- 安全漏洞防护:
- 输入校验与输出编码,防止XSS/注入。
- 速率限制与防重放攻击。
- 安全头配置(HSTS、CSP等)。
[本节为通用指导,不直接分析具体文件]