Consider defining a bean of type 'org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository' in your configuration

21,371

Solution 1

I am using spring boot 2.3.1.RELEASE I had the same problem, my pom.xml contained both these dependencies in my pom.xml

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

I removed the following dependency and that did the trick for me :

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

Not saying this will resolve your hassle but this might also be a dependency conflict issue for you.

This other post put me on track : Reactive OAuth2 with Spring Security 5.3.2 ReactiveClientRegistrationRepository bean could not be found

Solution 2

Your spring-boot configuration is perfect.


Root cause of the issue: The problem is in application.yaml. Either the configuration is wrong or not picked from the environment.

So, the problem is not the OAuth2 version but the configuration in application.yaml.

Note : ReactiveClientRegistrationRepository bean is created only when you configure the client with the OAuth2 application owner details.


I created a new project from start.spring.io and used your configuration in that.

And after running the project with your configuration, I was facing the same issue.

Error log :

***************************
APPLICATION FAILED TO START
***************************

Description:

Parameter 0 of method webClient in com.example.sampleoauth2.WebClientConfig required a bean of type 'org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository' that could not be found.

The following candidates were found but could not be injected:
    - Bean method 'clientRegistrationRepository' in 'ReactiveOAuth2ClientConfigurations.ReactiveClientRegistrationRepositoryConfiguration' not loaded because OAuth2 Clients Configured Condition registered clients is not available


Action:

Consider revisiting the entries above or defining a bean of type 'org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository' in your configuration.

Then, I saw that I didn't configure properties in application.yml file.

I read Spring Boot and OAuth2.0 Docs about how to get client-id and client-secret from github (Example) as you register your spring-boot app as OAuth app in that.

As soon as, I configured my application started to work.


I'm using spring-boot 2.3.1.RELEASE and OAuth2Client version 5.3.3.

My pom.xml :

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.1.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>sampleOauth2</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sampleOauth2</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-oauth2-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectreactor</groupId>
            <artifactId>reactor-spring</artifactId>
            <version>1.0.1.RELEASE</version>
        </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>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

My client github registration properties for application.yml:

spring:
  security:
    oauth2:
      client:
        registration:
          github:
            client-id: 22a7100de41c7308d346
            client-secret: 05910ab890be29579e9c183443d92e756c450aaf

Your updated WebClientConfig @Configuration class :

package com.example.sampleoauth2;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction;
import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;

import reactor.core.publisher.Mono;

@Configuration
public class WebClientConfig {

    public static Logger log = LogManager.getLogger();

    @Bean
    public WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations,
            ServerOAuth2AuthorizedClientRepository authorizedClients) {
        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
                clientRegistrations, authorizedClients);
        oauth.setDefaultOAuth2AuthorizedClient(true);
        return WebClient.builder().filter(oauth).filter(this.logRequest()).build();
    }

    private ExchangeFilterFunction logRequest() {
        return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
            log.info("Request: [{}] {}", clientRequest.method(), clientRequest.url());
            log.debug("Payload: {}", clientRequest.body());
            return Mono.just(clientRequest);
        });
    }
}

Success Log :

   .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.1.RELEASE)

2020-06-26 20:36:08.380  INFO 15956 --- [           main] c.e.s.SampleOauth2Application            : Starting SampleOauth2Application on Anishs-MacBook-Pro.local with PID 15956 (/Users/anish/Downloads/sampleOauth2/target/classes started by anish in /Users/anish/Downloads/sampleOauth2)
2020-06-26 20:36:08.381  INFO 15956 --- [           main] c.e.s.SampleOauth2Application            : No active profile set, falling back to default profiles: default
2020-06-26 20:36:08.935  INFO 15956 --- [           main] ctiveUserDetailsServiceAutoConfiguration : 

Using generated security password: 7c63302f-f913-4aa1-852d-cb8445719acb

2020-06-26 20:36:09.132  INFO 15956 --- [           main] o.s.b.web.embedded.netty.NettyWebServer  : Netty started on port(s): 8080
2020-06-26 20:36:09.138  INFO 15956 --- [           main] c.e.s.SampleOauth2Application            : Started SampleOauth2Application in 0.978 seconds (JVM running for 1.313)

Solution 3

I used the configurations that @AnishB. suggested as answer but still got the error:

Parameter 0 of method webClient in com.example.sampleoauth2.WebClientConfig required a bean of type 'org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository' that could not be found.

So, i had to use these dependencies with spring 2.3.1.RELEASE:

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

And this the WebClientConfig class:

@Configuration
public class WebClientConfig {

    private static final Logger log = LoggerFactory.getLogger(WebClientConfig.class);

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

    @Bean(name = "keycloak")
    WebClient webClient(@Qualifier("cr") ReactiveClientRegistrationRepository clientRegistrations) {
        ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
        oauth.setDefaultClientRegistrationId("keycloak");
        return WebClient.builder()
                .filter(oauth)
                .filter(logRequest())
                .build();
    }

    private ExchangeFilterFunction logRequest() {
        return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
            log.info("Request: [{}] {}", clientRequest.method(), clientRequest.url());
            log.debug("Payload: {}", clientRequest.body());

            return Mono.just(clientRequest);
        });
    }
}

and everything works fine, but it is question for me that why the solution of @AnishB. didn't worked for me?!

Share:
21,371
raj03
Author by

raj03

I am developer by profession, always looks for problem and active contributor to the medium.com and scn.sap.com.

Updated on February 17, 2022

Comments

  • raj03
    raj03 about 2 years

    I am using spring oAuthClient version 5.2.4.RELEASE By following the document link of spring security https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2Client-authorized-manager-provider

        import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository;
    import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction;
    import org.springframework.security.oauth2.client.web.server.ServerOAuth2AuthorizedClientRepository;
    import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
    import org.springframework.web.reactive.function.client.WebClient;
    
    import lombok.AllArgsConstructor;
    import lombok.extern.slf4j.Slf4j;
    import reactor.core.publisher.Mono;
    
    @AllArgsConstructor
    @Configuration
    @Slf4j
    public class WebClientConfig {
    
        @Bean("AuthProvider")
        WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations, ServerOAuth2AuthorizedClientRepository authorizedClients) {
            ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
                    clientRegistrations,
                    authorizedClients);
            oauth.setDefaultOAuth2AuthorizedClient(true);
            oauth.setDefaultClientRegistrationId("AuthProvider");
            return WebClient.builder()
                    .filter(oauth)
                    .filter(this.logRequest())
                    .build();
        }
    
    
        private ExchangeFilterFunction logRequest() {
            return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
                log.info("Request: [{}] {}", clientRequest.method(), clientRequest.url());
                log.debug("Payload: {}", clientRequest.body());
                return Mono.just(clientRequest);
            });
        }
    

    application.yaml

       security:
        oauth2:
          client:
            provider:
              AuthProvider:
                token-uri: ${tokenpath<read from environment variable>}
            registration:
              AuthProvider:
                authorization-grant-type: client_credentials
                client-id: ${<read from environment variable>}
                client-secret: ${<read from environment variable>}
    

    Getting the following error

        ***************************
    APPLICATION FAILED TO START
    ***************************
    
    Description:
    
    Parameter 0 of method webClient in com.sample.config.WebClientConfig required a bean of type 'org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository' that could not be found.
    
    The injection point has the following annotations:
        - @org.springframework.beans.factory.annotation.Autowired(required=true)
    
    
    Action:
    
    Consider defining a bean of type 'org.springframework.security.oauth2.client.registration.ReactiveClientRegistrationRepository' in your configuration.
    

    Let me know, if I missed any configuration as didnot get any specific help from other questions of stackoverflow

  • Anish B.
    Anish B. almost 4 years
    @BryanMusial Is this helpful ?
  • Bryan Musial
    Bryan Musial almost 4 years
    Yes, though in my own case the root cause was not the app config, but some commingling of Servlet and Reactive components. Once correcting those references my solution began to work. That said, thank you for throwing together an example; Bounty awarded!
  • Anish B.
    Anish B. almost 4 years
    This spring-boot-starter-oauth2-client and spring-boot-starter-webflux is already prsent in my pom.xml. Please check it properly.
  • Anish B.
    Anish B. almost 4 years
    That's why I added my pom.xml
  • Anish B.
    Anish B. almost 4 years
    It depends I lot of factors are there for getting this error.
  • Rasool Ghafari
    Rasool Ghafari almost 4 years
    Yes, i know that you used spring-boot-starter-oauth2-client and spring-boot-starter-webflux, i used as same as you used in the pom.xml, but didn't worked for me and i had to use my own configurations that i found it at manhtai.github.io/posts/…
  • Rasool Ghafari
    Rasool Ghafari almost 4 years
    It is very exciting for me that your configurations didn't worked for me and interesting to know the reason.
  • SoftwareSavant
    SoftwareSavant over 3 years
    Any chance you could be more specific Bryan? I am facing a similar issue and I am pretty bare bones ... Which servlet and which reactive components where in the same project?
  • ZahraAsgharzade
    ZahraAsgharzade over 2 years
    just this kind of configuration helped me . thanks
  • KevinBui
    KevinBui about 2 years