How can I access with WebClient a resource that is protected via the Oauth2 'Password' grant type?
Connecting with Oauth2 'client-credentials' works. In this case I need the password grant type.
I get this error:
401 Unauthorized from GET http://localhost:8086/test2 at org.springframework.web.reactive.function.client.WebClientResponseException.create(WebClientResponseException.java:198) ~[spring-webflux-5.3.19.jar:5.3.19]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
*__checkpoint ⇢ 401 from GET http://localhost:8086/test2
I configured the auth server via Keycloack with Access Type 'public'. I checked accessing a token via Postman. You can find more details via this post.
The Websecurity config (working for grant-type client-credentials):
@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("*").permitAll();
}
}
The webclient is created as a Bean. It works for the client-credentials grant type.
@Configuration
public class WebClientOAuth2Config {
@Bean("method2")
WebClient webClientGrantPassword( @Qualifier("authclientmgr2") OAuth2AuthorizedClientManager authorizedClientManager2) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client2 =
new ServletOAuth2AuthorizedClientExchangeFilterFunction(
authorizedClientManager2);
oauth2Client2.setDefaultClientRegistrationId("businesspartners");
return WebClient.builder().apply(oauth2Client2.oauth2Configuration()).build();
}
@Bean("authclientmgr2")
public OAuth2AuthorizedClientManager authorizedClientManager2(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder()
.clientCredentials()
.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
}
}
The controller accessing the resource server:
@RestController
public class Test2Controller {
@Autowired
private @Qualifier("method2") WebClient webClient2;
@GetMapping("/test2")
public String test2() {
return webClient2.get().uri("http://localhost:8086/test2")
.attributes(clientRegistrationId("businesspartners"))
.retrieve().bodyToMono(String.class).block();
}
}
The application.yml config is:
server:
port: 8081
spring:
security:
oauth2:
client:
registration:
businesspartners:
client-id: myclient2
authorization-grant-type: password
client-name: johan
client-secret: password
provider:
businesspartners:
issuer-uri: http://localhost:28080/auth/realms/realm2
token-uri: http://localhost:28080/auth/realms/realm2/protocol/openid-connect/token
The maven dependencies include:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>