Ste*_*erg 4 spring-security oauth-2.0
我正在使用 Spring Security 5.5 执行访问令牌请求,最近升级到 5.5.1,现在我的客户端密钥被我的 OAuth 2.0 提供商拒绝。这是由根据RFC 6749 第 2.3.1 节对 URL 编码客户端凭据进行错误修复引起的。
由于我的 OAuth 2.0 提供程序不合规,我想恢复到 Spring Security 5.5.0 中的旧行为,并发送不带 URL 编码的客户端凭据。
从参考文档中,如果我定义 a@Bean类型OAuth2AuthorizedClientManager:
@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
// @formatter:off
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager =
new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
// @formatter:on
return authorizedClientManager;
}
Run Code Online (Sandbox Code Playgroud)
如何将其配置为使用自定义转换器来设置凭据?
注意:与此问题相关,但涉及 Servlet 支持,而不是 WebClient 的响应式支持。
假设您有以下配置:
spring:
security:
oauth2:
client:
registration:
test-client:
provider: spring
client-id: aladdin
client-secret: "open sesame"
authorization-grant-type: client_credentials
redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
scope: resource:read
provider:
spring:
authorization-uri: http://auth-server:9000/oauth/authorize
token-uri: http://auth-server:9000/oauth/token
Run Code Online (Sandbox Code Playgroud)
在OP的示例中,OAuth2AuthorizedClientManager支持client_credentials授予访问令牌请求。这对前任很有用。如果我们想实现以下(虚构的)端点:
@RestController
public class TokenController {
@GetMapping("/token")
public OAuth2AccessToken token(@RegisteredOAuth2AuthorizedClient("test-client") OAuth2AuthorizedClient testClient) {
return testClient.getAccessToken();
}
}
Run Code Online (Sandbox Code Playgroud)
提供OAuth2AuthorizedClientManager了OAuth2AuthorizedClient本示例中注入的 。它可以使用自定义转换器进行配置,如下所示:
注意:以下是改编自参考文档的客户端凭据部分的扩展示例。
@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
// @formatter:off
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials((builder) ->
builder.accessTokenResponseClient(clientCredentialsAccessTokenResponseClient())
.build())
.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager =
new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
// @formatter:on
return authorizedClientManager;
}
@Bean
public OAuth2AccessTokenResponseClient<OAuth2ClientCredentialsGrantRequest> clientCredentialsAccessTokenResponseClient() {
// @formatter:off
OAuth2ClientCredentialsGrantRequestEntityConverter requestEntityConverter =
new OAuth2ClientCredentialsGrantRequestEntityConverter();
requestEntityConverter.setHeadersConverter(headersConverter());
DefaultClientCredentialsTokenResponseClient accessTokenResponseClient =
new DefaultClientCredentialsTokenResponseClient();
accessTokenResponseClient.setRequestEntityConverter(requestEntityConverter);
// @formatter:on
return accessTokenResponseClient;
}
private static <T extends AbstractOAuth2AuthorizationGrantRequest> Converter<T, HttpHeaders> headersConverter() {
// @formatter:off
Converter<T, ClientRegistration> clientRegistrationConverter =
AbstractOAuth2AuthorizationGrantRequest::getClientRegistration;
return clientRegistrationConverter
.andThen((clientRegistration) -> {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON_UTF8));
headers.setContentType(MediaType.valueOf(MediaType.APPLICATION_FORM_URLENCODED_VALUE + ";charset=UTF-8"));
headers.setBasicAuth(clientRegistration.getClientId(), clientRegistration.getClientSecret());
return headers;
});
// @formatter:on
}
Run Code Online (Sandbox Code Playgroud)
如果我们想支持authorization_code登录应用程序的授权,我们可以使用以下配置(其中包含上述方法和@Bean定义):
@Configuration
@EnableWebSecurity
public class SecurityConfiguration {
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
// @formatter:off
http
.authorizeRequests(authorizeRequests -> authorizeRequests
.anyRequest().authenticated())
.oauth2Login(oauth2Login -> oauth2Login
.tokenEndpoint(tokenEndpoint -> tokenEndpoint
.accessTokenResponseClient(authorizationCodeAccessTokenResponseClient())));
// @formatter:on
return http.build();
}
@Bean
public OAuth2AccessTokenResponseClient<OAuth2AuthorizationCodeGrantRequest> authorizationCodeAccessTokenResponseClient() {
// @formatter:off
OAuth2AuthorizationCodeGrantRequestEntityConverter requestEntityConverter =
new OAuth2AuthorizationCodeGrantRequestEntityConverter();
requestEntityConverter.setHeadersConverter(headersConverter());
DefaultAuthorizationCodeTokenResponseClient accessTokenResponseClient =
new DefaultAuthorizationCodeTokenResponseClient();
accessTokenResponseClient.setRequestEntityConverter(requestEntityConverter);
// @formatter:on
return accessTokenResponseClient;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4869 次 |
| 最近记录: |