gpt4 book ai didi

spring-security - 如何自定义 OAuth2 token 请求的授权 header

转载 作者:行者123 更新时间:2023-12-05 03:40:02 26 4
gpt4 key购买 nike

我正在使用 Spring Security 5.5 执行访问 token 请求并最近升级到 5.5.1,现在我的客户端密码被我的 OAuth 2.0 提供商拒绝。这是由 a bug fix 引起的根据 RFC 6749 Section 2.3.1 对客户端凭据进行 URL 编码.

由于我的 OAuth 2.0 提供程序不兼容,我想恢复到 Spring Security 5.5.0 中的旧行为,并在不使用 URL 编码的情况下发送我的客户端凭据。

来自reference documentation ,如果我定义了 OAuth2AuthorizedClientManager 类型的 @Bean:

    @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;
}

如何配置它以使用自定义转换器来设置凭据?

注意:this question有关但解决了 Servlet 支持而不是 WebClient 的 Reactive 支持。

最佳答案

假设您有以下配置:

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

在 OP 的示例中,OAuth2AuthorizedClientManager 支持 client_credentials 授权以发出访问 token 请求。这对前任很有用。如果我们想要实现以下(虚构的)端点:

@RestController
public class TokenController {
@GetMapping("/token")
public OAuth2AccessToken token(@RegisteredOAuth2AuthorizedClient("test-client") OAuth2AuthorizedClient testClient) {
return testClient.getAccessToken();
}
}

OAuth2AuthorizedClientManager 提供了在此示例中注入(inject)的 OAuth2AuthorizedClient。它可以使用自定义转换器进行配置,如下所示:

注意:以下是改编自 Client Credentials section 的扩展示例引用文档。

    @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
}

如果我们想要支持登录到应用程序的authorization_code授权,我们可以使用以下配置(使用上述方法和包含在其中的@Bean定义):

@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;
}

// ...

}

关于spring-security - 如何自定义 OAuth2 token 请求的授权 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68323767/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com