領先一步
VMware 提供培訓和認證,以加速您的進展。
了解更多我很興奮地分享,Spring Security 6.3 將支援 OAuth 2.0 令牌交換授權 (RFC 8693),此功能現已在最新的里程碑版本 (6.3.0-M3) 中提供預覽。此支援提供了將令牌交換與 OAuth2 用戶端 一起使用的能力。同樣地,伺服器端支援也隨著 Spring Authorization Server 1.3 版本一同發布,並且現已在最新的里程碑版本 (1.3.0-M3) 中提供預覽。
Spring Security 的 OAuth2 用戶端功能讓我們能夠輕鬆地向使用 OAuth2 持有者令牌保護的 API 發出受保護資源請求。同樣地,Spring Security 的 OAuth2 資源伺服器功能讓我們能夠使用 OAuth2 保護 API。讓我們看看如何使用新的支援來建構具有令牌交換的 OAuth2 流程。
讓我們想像一下,我們有一個名為 user-service
的資源伺服器,提供用於存取使用者資訊的 API。為了向 user-service
發出請求,用戶端必須提供訪問令牌。假設令牌必須具有 user-service
的受眾 (aud
聲明)。這可能看起來像以下的 Spring Boot 配置屬性
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://my-auth-server.com
audiences: user-service
現在讓我們想像一下,我們想要引入一個名為 message-service
的新資源伺服器,並從 user-service
呼叫它。然後假設此新服務的令牌必須具有 message-service
的受眾。顯然,我們無法在對 message-service
的請求中重複使用來自對 user-service
的請求的令牌。但是,我們希望保留原始請求中用戶的身分。我們該如何完成此操作?
為了獲得 message-service
所需的訪問令牌,資源伺服器 user-service
必須成為用戶端並交換現有的令牌,以獲得保留原始令牌身分 (使用者) 的新令牌。這稱為 「模擬」,並且正是 OAuth 2.0 令牌交換旨在解決的情境。
為了啟用令牌交換,我們需要將 user-service
配置為同時充當資源伺服器和可以使用令牌交換的用戶端,如下列 Spring Boot 配置屬性所示
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: https://my-auth-server.com
audiences: user-service
client:
registration:
my-token-exchange-client:
provider: my-auth-server
client-id: token-client
client-secret: token
authorization-grant-type: urn:ietf:params:oauth:grant-type:token-exchange
client-authentication-method: client_secret_basic
scope:
- message.read
provider:
my-auth-server:
issuer-uri: https://my-auth-server.com
我們還需要在 Spring Security 中啟用新授權類型的使用,我們可以通過發布以下 bean 來完成
@Bean
public OAuth2AuthorizedClientProvider tokenExchange() {
return new TokenExchangeOAuth2AuthorizedClientProvider();
}
這就是開始使用令牌交換所需的一切。但是,如果我們想要請求特定的 audience
或 resource
值,我們需要配置其他參數作為令牌請求的一部分,如下列範例所示
@Bean
public OAuth2AuthorizedClientProvider tokenExchange() {
var requestEntityConverter = new TokenExchangeGrantRequestEntityConverter();
requestEntityConverter.addParametersConverter((grantRequest) -> {
var parameters = new LinkedMultiValueMap<String, String>();
parameters.add(OAuth2ParameterNames.AUDIENCE, "message-service");
parameters.add(OAuth2ParameterNames.RESOURCE, "https://example.com/messages");
return parameters;
});
var accessTokenResponseClient = new DefaultTokenExchangeTokenResponseClient();
accessTokenResponseClient.setRequestEntityConverter(requestEntityConverter);
var authorizedClientProvider = new TokenExchangeOAuth2AuthorizedClientProvider();
authorizedClientProvider.setAccessTokenResponseClient(accessTokenResponseClient);
return authorizedClientProvider;
}
透過此配置到位,我們可以在一個資源伺服器中取得訪問令牌,並在對另一個資源伺服器的受保護資源請求中將其用作 Bearer
令牌。預設情況下,傳遞到資源伺服器中 Authorization
標頭中的原始持有者令牌將用於取得新的訪問令牌。
提示:請參閱參考文件中的 授權用戶端功能,以取得有關如何取得訪問令牌並使用此配置發出受保護資源請求的更多資訊。
為了完整呈現,讓我們使用 Spring Authorization Server 建構一個全新的授權伺服器應用程式來支援此流程。
使用具有 OAuth2 Authorization Server 依賴項的 Spring Initializr,我們可以使用以下 Spring Boot 配置屬性來配置功能完整的授權伺服器
spring:
security:
user:
name: sally
password: password
oauth2:
authorizationserver:
client:
test-client:
registration:
client-id: test-client
client-secret: {noop}secret
client-authentication-methods:
- client_secret_basic
authorization-grant-types:
- authorization_code
- refresh_token
scopes:
- user.read
token-client:
registration:
client-id: token-client
client-secret: {noop}token
client-authentication-methods:
- client_secret_basic
authorization-grant-types:
- urn:ietf:params:oauth:grant-type:token-exchange
scopes:
- message.read
與用戶端一樣,我們可能想要支援令牌交換的特定請求參數,例如 audience
或 resource
,我們可以透過發布以下 bean 來完成
@Bean
public OAuth2TokenCustomizer<JwtEncodingContext> accessTokenCustomizer() {
return (context) -> {
if (AuthorizationGrantType.TOKEN_EXCHANGE.equals(context.getAuthorizationGrantType())) {
OAuth2TokenExchangeAuthenticationToken tokenExchangeAuthentication = context.getAuthorizationGrant();
Set<String> resources = tokenExchangeAuthentication.getResources();
// TODO: Validate resource value(s) and map to the
// appropriate audience value(s) if needed...
context.getClaims().audience(...);
}
};
}
透過此配置到位,授權伺服器支援具有 OAuth 2.0 令牌請求的可選 resource
參數的令牌交換授權,並且能夠頒發令牌,允許資源伺服器充當用戶端並模擬最終使用者。
在這篇部落格文章中,我們討論了令牌交換的「模擬」用例,並探索了資源伺服器 (充當用戶端) 和授權伺服器的簡單配置。
希望您和我一樣對這項新支援感到興奮!我鼓勵您試用 Spring Authorization Server 中的 範例,其中包含這篇部落格文章的工作範例。也請在您自己的專案中試用 Spring Security 和 Spring Authorization Server 的里程碑版本。我們非常歡迎您的回饋!