使用spring网关和Oauth2配置客户端凭据流

时间:2019-12-02 13:09:50

标签: spring spring-boot spring-security spring-security-oauth2 spring-webflux

我的客户端应用程序(我的Spring Gateway)中的客户端凭据流配置存在一些问题。

我的授权服务器可以正常运行,并且可以与Postman进行测试。

但是在我的客户端应用程序中,似乎oauth2配置已损坏,没有编译错误。

当我在服务器资源上调用受保护的资源时,客户端应用程序似乎试图在其基础而非授权服务器中调用URL。

查看代码 我的配置文件:

security:
    oauth2:
      client:
        registration:
          apigateway:
            provider: apigateway
            client-id: apigateway
            client-secret: password
            scope: generate_token,read,write
            authorization-grant-type: client_credentials
            redirect-uri: "{baseUrl}/login/oauth2/code/{registrationId}"
        provider:
          apigateway:
            token-uri: https://localhost:9001/oauth/token

我的客户依赖性:

<dependencies>
        <!-- ************ SPRING DEPENDENCIES ************ -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-oauth2-client</artifactId>
            <version>5.2.1.RELEASE</version>
        </dependency>
    </dependencies>

我的WebClient的配置:

public class WebClientSecurityCustomizer implements WebClientCustomizer {

    private ServerOAuth2AuthorizedClientExchangeFilterFunction securityExchangeFilterFunction;

    public WebClientSecurityCustomizer(
            ServerOAuth2AuthorizedClientExchangeFilterFunction securityExchangeFilterFunction) {
        this.securityExchangeFilterFunction = securityExchangeFilterFunction;
    }

    @Override
    public void customize(WebClient.Builder webClientBuilder) {

        SslProvider sslProvider = SslProvider.builder().sslContext(
                SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE)
        )
                .defaultConfiguration(SslProvider.DefaultConfigurationType.NONE).build();

        TcpClient tcpClient = TcpClient.create().secure(sslProvider);
        HttpClient httpClient = HttpClient.from(tcpClient);
        ClientHttpConnector httpConnector = new ReactorClientHttpConnector(httpClient);
        webClientBuilder.clientConnector(httpConnector);

        webClientBuilder.filters((filterFunctions) -> {
            if (!filterFunctions.contains(this.securityExchangeFilterFunction)) {
                filterFunctions.add(0, this.securityExchangeFilterFunction);
            }
        });
    }
}

@Configuration
public class WebClientSecurityConfiguration {

    @Bean
    public WebClientSecurityCustomizer webClientSecurityCustomizer(
            ReactiveClientRegistrationRepository clientRegistrations) {

        // Provides support for an unauthenticated user such as an application
        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
                clientRegistrations, new UnAuthenticatedServerOAuth2AuthorizedClientRepository());

        // Build up a new WebClientCustomizer implementation to inject the oauth filter
        // function into the WebClient.Builder instance
        return new WebClientSecurityCustomizer(oauth);
    }

    /**
     * Helper function to include the Spring CLIENT_REGISTRATION_ID_ATTR_NAME in a
     * properties Map
     *
     * @param provider - OAuth2 authorization provider name
     * @return consumer properties Map
     */
    public static Consumer<Map<String, Object>> getExchangeFilterWith(String provider) {
        return ServerOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId(provider);
    }
}

我在资源上的呼叫者:

return webClientBuilder.build().get().uri(uri+"{accessToken}", accessToken)
                .attributes(
                        WebClientSecurityConfiguration.getExchangeFilterWith("apigateway"))
               .retrieve()
               .bodyToMono(String.class)
               .flatMap(response -> {
                   ServerHttpRequest request = exchange.getRequest().mutate()
                           .header(jwtHeader, String.format("%s %s", jwtPrefix, response))
                           .build();

                   return chain.filter(exchange.mutate().request(request).build());
               });
    }

最后,在客户端应用程序中生成的错误(似乎授权和资源服务未收到请求):

2019-12-02 13:53:50.543 ERROR 11492 --- [ctor-http-nio-2] a.w.r.e.AbstractErrorWebExceptionHandler : [405f3f3c]  500 Server Error for HTTP GET "/oauth2/authorization/apigateway"

java.lang.IllegalArgumentException: Invalid Authorization Grant Type (client_credentials) for Client Registration with Id: apigateway
    at org.springframework.security.oauth2.client.web.server.DefaultServerOAuth2AuthorizationRequestResolver.authorizationRequest(DefaultServerOAuth2AuthorizationRequestResolver.java:156) ~[spring-security-oauth2-client-5.2.1.RELEASE.jar:5.2.1.RELEASE]

非常感谢您的帮助。

0 个答案:

没有答案