OAuth2授权码流程与Spring Security集成
请详细解释OAuth2授权框架的四种授权模式(授权码模式/隐式模式/密码模式/客户端凭证模式),重点说明最安全的**授权码模式(Authorization Code)**完整流程。如何在Spring Security中配置OAuth2客户端和资源服务器?PKCE扩展解决了什么问题?
回答
孤独的心
四种授权模式
| 模式 | 适用场景 | 安全性 |
|---|---|---|
| 授权码模式 | 服务端Web应用 | ⭐⭐⭐⭐⭐ |
| 隐式模式(已废弃) | 纯前端(已被PKCE替代) | ⭐⭐ |
| 密码模式 | 受信任的第一方应用 | ⭐⭐⭐ |
| 客户端凭证模式 | 服务间通信(无用户) | ⭐⭐⭐⭐ |
授权码模式完整流程
1. 用户访问客户端 → 重定向到授权服务器
2. 用户登录并授权 → 授权服务器返回授权码(code)
3. 客户端用code + client_secret → 请求令牌
4. 授权服务器返回access_token + refresh_token
5. 客户端用access_token访问资源服务器
PKCE(Proof Key for Code Exchange)
解决的问题:授权码被拦截后,攻击者可用code换取token。
改进流程:
1. 客户端生成 code_verifier(随机字符串)
2. 计算 code_challenge = SHA256(code_verifier)
3. 授权请求带上 code_challenge + code_challenge_method=S256
4. 令牌请求带上 code_verifier
5. 授权服务器验证 SHA256(code_verifier) == code_challenge
Spring Security配置
OAuth2 Client(第三方登录)
spring:
security:
oauth2:
client:
registration:
github:
client-id: xxx
client-secret: xxx
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
google:
client-id: xxx
client-secret: xxx
Resource Server(API保护)
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://auth.example.com
@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http
.oauth2Login() // OAuth2登录
.and()
.oauth2ResourceServer() // 资源服务器
.jwt(Customizer.withDefaults());
return http.build();
}
}