Spring Security + OAuth2统一认证实战
2025.04.02
Java
7 min
2.9k 字
// 目录 · contents
前言
在微服务架构中,统一认证授权是核心基础设施之一。Spring Security作为Java生态中最成熟的安全框架,结合OAuth2协议,能够构建出灵活、安全的认证体系。本文将从Spring Security的核心架构出发,深入讲解OAuth2的各种授权流程,并给出完整的JWT集成方案。
Spring Security 核心架构
graph TB
Client[客户端请求] --> DFP[DelegatingFilterProxy]
DFP --> FCSB[FilterChainProxy]
FCSB --> SF1[SecurityFilterChain 1]
FCSB --> SF2[SecurityFilterChain 2]
subgraph SecurityFilterChain
F1[DisableEncodeUrlFilter]
F2[SecurityContextPersistenceFilter]
F3[HeaderWriterFilter]
F4[CsrfFilter]
F5[LogoutFilter]
F6[UsernamePasswordAuthenticationFilter]
F7[BearerTokenAuthenticationFilter]
F8[ExceptionTranslationFilter]
F9[AuthorizationFilter]
end
SF1 --> F1 --> F2 --> F3 --> F4 --> F5 --> F6 --> F7 --> F8 --> F9
F6 --> AM[AuthenticationManager]
AM --> AP1[DaoAuthenticationProvider]
AM --> AP2[JwtAuthenticationProvider]
AP1 --> UDS[UserDetailsService]
UDS --> DB[(数据库)]
style FCSB fill:#f96,stroke:#333
style AM fill:#9cf,stroke:#333
Spring Security的核心是一组Servlet Filter组成的过滤器链。每个请求都会按顺序经过这些过滤器,每个过滤器负责一个特定的安全功能。
核心组件说明
- FilterChainProxy:Spring Security的入口,管理多条SecurityFilterChain
- AuthenticationManager:认证管理器,委托给具体的AuthenticationProvider
- UserDetailsService:加载用户信息的核心接口
- SecurityContext:存储当前认证信息,通过ThreadLocal传递
OAuth2 授权流程
OAuth2定义了四种授权模式,其中最常用的是授权码模式和客户端凭证模式。
sequenceDiagram
participant User as 用户
participant Client as 客户端应用
participant AuthServer as 授权服务器
participant Resource as 资源服务器
Note over User,Resource: 授权码模式 (Authorization Code)
User->>Client: 1. 访问受保护资源
Client->>User: 2. 重定向到授权服务器
User->>AuthServer: 3. 登录并授权
AuthServer->>User: 4. 返回授权码(code)
User->>Client: 5. 携带授权码回调
Client->>AuthServer: 6. 用code换取access_token
AuthServer->>Client: 7. 返回access_token + refresh_token
Client->>Resource: 8. 携带access_token请求资源
Resource->>Client: 9. 返回受保护资源
OAuth2 各授权模式对比
| 模式 | 适用场景 | 安全性 | 是否涉及用户 |
|---|---|---|---|
| 授权码模式 | Web应用、SPA | 高 | 是 |
| PKCE模式 | 移动端、SPA | 高 | 是 |
| 客户端凭证 | 服务间通信 | 中 | 否 |
| 密码模式(已废弃) | 高度信任的应用 | 低 | 是 |
项目实战搭建
1. 依赖配置
1 | |
2. 自定义 UserDetailsService
1 | |
3. JWT 令牌服务
1 | |
4. JWT 认证过滤器
1 | |
5. Security 配置类
1 | |
6. 认证控制器
1 | |
RBAC 权限模型
erDiagram
SYS_USER ||--o{ USER_ROLE : has
SYS_ROLE ||--o{ USER_ROLE : has
SYS_ROLE ||--o{ ROLE_PERMISSION : has
SYS_PERMISSION ||--o{ ROLE_PERMISSION : has
SYS_USER {
bigint id PK
varchar username UK
varchar password
boolean enabled
boolean locked
datetime created_at
}
SYS_ROLE {
bigint id PK
varchar code UK
varchar name
varchar description
}
SYS_PERMISSION {
bigint id PK
varchar code UK
varchar name
varchar resource_url
varchar method
}
USER_ROLE {
bigint user_id FK
bigint role_id FK
}
ROLE_PERMISSION {
bigint role_id FK
bigint permission_id FK
}
方法级权限控制
1 | |
自定义权限评估器
1 | |
异常处理
1 | |
安全最佳实践
Token过期策略:Access Token设置较短的过期时间(15-60分钟),通过Refresh Token续期。Refresh Token可以存储在数据库中并支持撤销。
密码安全:始终使用BCrypt等自适应哈希算法存储密码,设置合理的cost factor(建议12+)。
CORS配置:生产环境严格限制允许的Origin,不要使用
*通配符。
1 | |
防止暴力破解:实现登录失败次数限制,可以结合Redis实现滑动窗口计数。
日志审计:记录所有认证事件(登录成功/失败、Token刷新、权限拒绝),便于安全审计和问题排查。
HTTPS强制:生产环境必须使用HTTPS,防止Token在传输过程中被截获。
总结
本文从Spring Security的过滤器链架构出发,讲解了OAuth2的授权流程和JWT令牌机制,并给出了完整的统一认证实战方案。核心要点:
- Spring Security基于过滤器链实现安全控制,理解过滤器的执行顺序是关键
- JWT是无状态认证的首选方案,但需要配合合理的过期策略和刷新机制
- RBAC模型通过用户-角色-权限的三级结构实现灵活的访问控制
@PreAuthorize和自定义权限评估器可以实现细粒度的方法级权限控制- 安全是系统工程,需要从传输层(HTTPS)、认证层(JWT)、授权层(RBAC)到审计层(日志)全面考虑
$ echo "comments" · 评论