0

I am trying to set a Spring WebClient instance to use OAuth 2.0 authentication with the password grant type, but I am not sure about how to properly set the username and the password.

In my application, the relevant parameters are received in the form of a Map<String, String> and not loaded from any application.yaml file. For this reason, I'm trying to do it programatically (i.e., without the use of beans) - my approach might be wrong to begin with.

This is my non-working solution:

{
    OAuth20Info oAuth20Info = (OAuth20Info) parameters.getAuthenticationInfo();

    ClientRegistration registration = ClientRegistrations.fromOidcIssuerLocation(oAuth20Info.getHost() + ":" + oAuth20Info.getPort()) // host, port
        .clientId(oAuth20Info.getClientId()) // clientId
        .tokenUri(oAuth20Info.getTokenUrlPath()) // tokenUrlPath
        .authorizationGrantType(AuthorizationGrantType.PASSWORD) // grantType
        // TODO: How to set: username, password?
        .build();

    ReactiveClientRegistrationRepository clientRegistrations = new InMemoryReactiveClientRegistrationRepository(registration);

    ServerOAuth2AuthorizedClientExchangeFilterFunction oauth =
        new ServerOAuth2AuthorizedClientExchangeFilterFunction(
            clientRegistrations,
            new UnAuthenticatedServerOAuth2AuthorizedClientRepository());

    return WebClient.builder().filter(oauth).build();
}

Hence, I don't know where I need to set the username and password. According to this: "The latest OAuth 2.0 Security Best Current Practice disallows the password grant entirely", so I am not sure if it is even supported.

I would expect to be able to set the username and password within the builder for the ClientRegistration instance, but it is not possible.

So how could I set the username and password values in order to access some protected resource with password grant type credentials? Thanks in advance.

Relevant part of my dependencies:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-webflux</artifactId>
  <version>5.2.3.RELEASE</version>
</dependency>
<dependency>
  <groupId>io.projectreactor.netty</groupId>
  <artifactId>reactor-netty</artifactId>
  <version>0.9.4.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>5.1.7.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>5.1.7.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework.security</groupId>
  <artifactId>spring-security-oauth2-client</artifactId>
  <version>5.2.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework.security.oauth</groupId>
  <artifactId>spring-security-oauth2</artifactId>
  <version>2.3.7.RELEASE</version>
</dependency>
<dependency>
Guimo
  • 632
  • 1
  • 7
  • 15
  • It's documented in the reference: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2Client-authorized-manager-provider AND https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2Client-password-grant – Joe Grandja Apr 06 '20 at 19:10

1 Answers1

-1

You can try:

        WebClient.builder()
            .filter(ExchangeFilterFunctions
                .basicAuthentication(configuration.getClientId(), configuration.getClientSecret()))
            .build()
            .post()
            .uri(...)
            ...

You can use the ExchangeFilterFunctions class to add an authorization header to a request.

Another way:

        WebClient.builder()
            .defaultHeaders(header -> header.setBasicAuth(userName, password))
            ...
V. Mokrecov
  • 1,014
  • 1
  • 11
  • 20