SpringSecurity5和oauth2中的客户端凭据流不能通过使用SpringWebClient工作

ttygqcqt  于 2021-07-23  发布在  Java
关注(0)|答案(0)|浏览(281)

SpringSecurity5中的客户端凭据流对我不起作用,我使用的是pringboot:2.3.2.release

1:在纯webflux环境下

请检查https://github.com/neuw/oauth2-spring-boot-client.git 我克隆了它并在本地机器上运行,但是源代码不起作用,它出现了错误,它似乎试图从auth服务器获取访问令牌,但是api调用失败,并显示了一些混淆消息。终结点http://localhost:9090/oauth2/token为我工作,我刚通过 Postman 测试

Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException: 
Error has been observed at the following site(s):
    |_ checkpoint ⇢ Body from POST http://localhost:9090/oauth2/token [DefaultClientResponse]
Stack trace:
        at org.springframework.security.oauth2.core.web.reactive.function.OAuth2AccessTokenResponseBodyExtractor.oauth2AccessTokenResponse(OAuth2AccessTokenResponseBodyExtractor.java:104) ~[spring-security-oauth2-core-5.3.3.RELEASE.jar:5.3.3.RELEASE]
OAuth2AccessTokenResponseBodyExtractor.java:104

2:组合环境(springwebflux+springwebflux)

在组合环境中,我使用的是类似的配置,它引用了git address中的源代码,但无论我如何调整下面的配置,当webclient调用远程url时总是出现错误消息:

2021-02-16 17:46:47.201 DEBUG 13340 --- [io-9191-exec-10] o.s.s.w.a.ExceptionTranslationFilter     : Access is denied (user is anonymous); redirecting to authentication entry point

org.springframework.security.access.AccessDeniedException: Access is denied
    at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-5.3.3.RELEASE.jar:5.3.3.RELEASE]
AffirmativeBased.java:84
    at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:233) ~[spring-security-core-5.3.3.RELEASE.jar:5.3.3.RELEASE]

顺便说一句,在组合环境中,bean reactiveoauth2authorizedclientmanager找不到它的两个输入参数,因此我必须手动初始化它:

@Bean
    public ReactiveOAuth2AuthorizedClientManager authorizedClientManager( final ReactiveClientRegistrationRepository clientRegistrationRepository, final ServerOAuth2AuthorizedClientRepository authorizedClientRepository) {
        ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder()
                .clientCredentials()
                .build();

        DefaultReactiveOAuth2AuthorizedClientManager authorizedClientManager = new DefaultReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientRepository);

        authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
        return authorizedClientManager;
    }
@Bean("reactiveClientRegistrationRepository")
    ReactiveClientRegistrationRepository getRegistration(
            @Value("${spring.security.oauth2.client.provider.my-auth.token-uri}") String tokenUri,
            @Value("${spring.security.oauth2.client.registration.my-auth.client-id}") String clientId,
            @Value("${spring.security.oauth2.client.registration.my-auth.client-secret}") String clientSecret,
            @Value("${spring.security.oauth2.client.registration.my-auth.scope}") String scope
    ) {
        ClientRegistration registration = ClientRegistration
                .withRegistrationId("my-auth")
                .tokenUri(tokenUri)
                .clientId(clientId)
                .clientSecret(clientSecret)
                .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
                .scope(scope)
                .build();
        return new InMemoryReactiveClientRegistrationRepository(registration);
    }

    @Bean("serverOAuth2AuthorizedClientRepository")
    ServerOAuth2AuthorizedClientRepository getAuthorizedClient (ReactiveClientRegistrationRepository reactiveClientRegistrationRepository) {
        ReactiveOAuth2AuthorizedClientService authorizedClientService = new InMemoryReactiveOAuth2AuthorizedClientService(reactiveClientRegistrationRepository);
        return new AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository(authorizedClientService);
    }

spring webclient创建代码:

@Bean("myAuthWebClient")
    public WebClient webClient( ReactiveOAuth2AuthorizedClientManager authorizedClientManager) {

        String registrationId = "my-auth";

        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
        // for telling which registration to use for the webclient
        oauth.setDefaultClientRegistrationId(registrationId);
        return WebClient.builder()
                // base path of the client, this way we need to set the complete url again
                .baseUrl(testClientBaseUrl)
                .filter(oauth)
                .filter(logRequest())
                .filter(logResponse())
                .build();
    }

下面是spring webclient调用内省端点的源代码:

private Mono<ResponseEntity> makeRequest(String token) {
        LinkedMultiValueMap map = new LinkedMultiValueMap();
        map.add("token", token);
        return this.webClient.post().uri(this.introspectUrl)
        .accept(MediaType.APPLICATION_JSON)
                .body(BodyInserters.fromMultipartData(map)).retrieve().bodyToMono(ResponseEntity.class);
    }

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题