简体   繁体   English

Spring 使用自定义请求配置 WebClient Oauth2 身份验证

[英]Spring Configuring WebClient Oauth2 Authentication with Custom Request

I'm having some trouble understanding how to customize an authentication request made using Oauth2 when applying a ServerOAuth2AuthorizedClientExchangeFilterFunction filter on a WebClient.Builder that is used as a base for all WebClient instances.在用作所有WebClient实例的基础的WebClient.Builder上应用ServerOAuth2AuthorizedClientExchangeFilterFunction过滤器时,我无法理解如何自定义使用 Oauth2 发出的身份验证请求。

The system itself is working, and the request is generated according to Oauth2 specifications.系统本身在工作,请求是根据Oauth2规范生成的。 However, my authentication service has some extra fields that need to be present in order for the authentication to work.但是,我的身份验证服务有一些额外的字段需要存在才能使身份验证工作。 That's the problem, so far I couldn't find any reasonable way of adding the field that I need or customizing the request itself.这就是问题所在,到目前为止,我找不到任何合理的方法来添加我需要的字段或自定义请求本身。

The only wat I could find so far would be to implement a ReactiveOAuth2AuthorizedClientManager .到目前为止,我唯一能找到的就是实现ReactiveOAuth2AuthorizedClientManager But I'm quite resistant about doing that, since there is no generic implementation of that interface that I can extend, and all available implementations are final and can't be extended.但是我对此非常抗拒,因为没有可以扩展的该接口的通用实现,并且所有可用的实现都是final的并且不能扩展。 Since my use case would be only to add a field to the request body, I hope there is a better way of achieving that.由于我的用例只是向请求正文添加一个字段,我希望有更好的方法来实现这一点。

Any help would be highly appreciated.任何帮助将不胜感激。 Thanks for your time.谢谢你的时间。

What I want to achieve我想要达到的目标

  • Add a field to the authentication Oauth2 request, managed by spring security向身份验证 Oauth2 请求添加一个字段,由 spring 安全管理

What's getting in the way有什么阻碍

  • Couldn't find a way to customize adding custom fields to the authentication request.找不到自定义向身份验证请求添加自定义字段的方法。 There is too much voodoo magic happening behind the curtain.幕后发生了太多的巫术魔法。

Configuration配置

@Configuration
public class WebClientConfig {

    @Bean("azure")
    public ReactiveClientRegistrationRepository getRegistration(
            @Value("${spring.security.oauth2.client.provider.azure.token-uri}")
            String tokenUri,
            @Value("${spring.security.oauth2.client.registration.azure.client-id}")
            String clientId,
            @Value("${spring.security.oauth2.client.registration.azure.client-secret}")
            String clientSecret,
            @Value("${spring.security.oauth2.client.registration.azure.authorization-grant-type}")
            String authorizationGrantType
    )
    {
        ClientRegistration registration = getClientRegistration(
                "azure",
                tokenUri,
                clientId,
                clientSecret,
                getAuthorizationGrantType(authorizationGrantType)
        );
        return new InMemoryReactiveClientRegistrationRepository(registration);
    }

    protected AuthorizationGrantType getAuthorizationGrantType(@Value("${spring.security.oauth2.client.registration.azure.authorization-grant-type}") String authorizationGrantType) {
        return new AuthorizationGrantType(authorizationGrantType);
    }

    protected ClientRegistration getClientRegistration(
            String registrationId,
            String tokenUri,
            String clientId,
            String clientSecret,
            AuthorizationGrantType authorizationGrantType
    ) {
        return ClientRegistration
                    .withRegistrationId(registrationId)
                    .tokenUri(tokenUri)
                    .clientId(clientId)
                    .clientSecret(clientSecret)
                    .authorizationGrantType(authorizationGrantType)
                    .build();
    }

    @Bean
    public ServerOAuth2AuthorizedClientExchangeFilterFunction  oauth2AuthenticationFilter(
            @Qualifier("azure") ReactiveClientRegistrationRepository clientRegistrations
    ) {
        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
                clientRegistrations,
                        new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
        oauth.setDefaultClientRegistrationId("azure");
        oauth.setDefaultOAuth2AuthorizedClient(true);
        return oauth;
    }

    @Bean("base")
    public WebClient.Builder webClientBaseBuilder()
    {
        return WebClient.builder();
    }

    @Bean
    @Primary
    public WebClient.Builder webClientBuilderWithFilters(
            @Qualifier("base") WebClient.Builder baseBuilder,
            ServerOAuth2AuthorizedClientExchangeFilterFunction  oauth2AuthenticationFilter
    ) {
        return baseBuilder
                .filter(oauth2AuthenticationFilter);
    }

    @Bean
    public WebClient webClient(
            @Value("${api.appId}") String appId,
            @Value("${api.url}") String url,
            WebClient.Builder builder
    ) {
        return builder
                .baseUrl(url)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .defaultHeader("Application-Id", appId)
                .build();
    }

}

Refer to the spring security documentation, Assuming you are using client credentials grant请参阅 spring 安全文档,假设您正在使用客户端凭据授予

If you need to customize the pre-processing of the Token Request, you can provide DefaultClientCredentialsTokenResponseClient.setRequestEntityConverter() with a custom Converter<OAuth2ClientCredentialsGrantRequest, RequestEntity<?>>如果需要自定义Token Request的预处理,可以给DefaultClientCredentialsTokenResponseClient.setRequestEntityConverter()提供一个自定义的Converter<OAuth2ClientCredentialsGrantRequest, RequestEntity<?>>

https://docs.spring.io/spring-security/site/docs/current/reference/html5/#customizing-the-access-token-request-3 https://docs.spring.io/spring-security/site/docs/current/reference/html5/#customizing-the-access-token-request-3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM