# SpringBootSecurity中OAuth2.0自定義授權碼怎么寫
## 引言
在OAuth2.0授權流程中,授權碼(Authorization Code)模式是最常用的安全模式之一。Spring Security OAuth2提供了默認實現,但在實際開發中,我們經常需要自定義授權碼的生成、存儲和驗證邏輯以滿足業務需求。本文將詳細介紹如何在SpringBoot Security中實現自定義授權碼。
---
## 一、OAuth2.0授權碼模式回顧
### 1.1 標準流程
### 1.2 默認實現的問題
- 授權碼是隨機字符串,無法攜帶業務信息
- 授權碼存儲默認使用內存,分布式環境下需要改造
- 授權碼有效期固定(默認5分鐘)
---
## 二、自定義授權碼實現
### 2.1 核心接口分析
```java
// 授權碼服務接口
public interface AuthorizationCodeServices {
String createAuthorizationCode(OAuth2Authentication authentication);
OAuth2Authentication consumeAuthorizationCode(String code) throws InvalidGrantException;
}
Spring默認實現:RandomValueAuthorizationCodeServices
@Component
public class CustomAuthorizationCodeServices implements AuthorizationCodeServices {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// 授權碼前綴
private static final String CODE_PREFIX = "OAUTH_CODE:";
// 自定義授權碼生成(示例:業務前綴+時間戳+隨機數)
private String generateCode(OAuth2Authentication authentication) {
String clientId = authentication.getOAuth2Request().getClientId();
return "CUST_" + clientId + "_" +
System.currentTimeMillis() + "_" +
UUID.randomUUID().toString().substring(0,6);
}
@Override
public String createAuthorizationCode(OAuth2Authentication authentication) {
String code = generateCode(authentication);
redisTemplate.opsForValue().set(
CODE_PREFIX + code,
authentication,
5, // 5分鐘過期
TimeUnit.MINUTES);
return code;
}
@Override
public OAuth2Authentication consumeAuthorizationCode(String code) {
String key = CODE_PREFIX + code;
OAuth2Authentication auth = (OAuth2Authentication) redisTemplate.opsForValue().get(key);
redisTemplate.delete(key);
if(auth == null) {
throw new InvalidGrantException("Invalid authorization code: " + code);
}
return auth;
}
}
@Configuration
@EnableAuthorizationServer
public class AuthServerConfig extends AuthorizationServerConfigurerAdapter {
@Autowired
private CustomAuthorizationCodeServices customAuthorizationCodeServices;
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.authorizationCodeServices(customAuthorizationCodeServices)
// 其他配置...
;
}
}
// 在生成授權碼時嵌入業務ID
public String generateCode(OAuth2Authentication authentication) {
User user = (User) authentication.getUserAuthentication().getPrincipal();
String businessId = getBusinessId(user); // 獲取業務ID
Map<String, Object> additionalInfo = new HashMap<>();
additionalInfo.put("businessId", businessId);
((DefaultOAuth2AccessToken)accessToken).setAdditionalInformation(additionalInfo);
return "BIZ_" + businessId + "_" + UUID.randomUUID();
}
# application.yml
spring:
redis:
host: redis-cluster.example.com
timeout: 3000
// 添加監控邏輯
@Override
public OAuth2Authentication consumeAuthorizationCode(String code) {
// ...原有邏輯
// 記錄日志
auditLogService.logCodeUsage(
code,
auth.getOAuth2Request().getClientId(),
auth.getUserAuthentication().getName()
);
return auth;
}
curl -X GET \
'http://localhost:8080/oauth/authorize?response_type=code&client_id=test_client&redirect_uri=http://example.com'
觀察返回的授權碼格式:
CUST_test_client_1621234567890_3a7b5f
redis-cli
> KEYS "OAUTH_CODE:*"
> GET "OAUTH_CODE:CUST_test_client_1621234567890_3a7b5f"
安全性:
性能:
兼容性:
通過自定義AuthorizationCodeServices接口,我們可以靈活控制OAuth2.0授權碼的生成和管理邏輯。本文展示了基于Redis的分布式存儲方案,實際開發中可根據需求選擇數據庫或其他存儲方式。更復雜的場景還可以結合JWT等技術實現無狀態授權碼。
完整示例代碼:https://github.com/example/spring-oauth2-custom-code “`
(全文約1050字)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。