I am attempting to get a bearer token via a webclient with the following setup for an integration test of a secured resource server in a servlet application.
spring:
security:
oauth2:
client:
registration:
idp:
clientId: id
clientSecret: secret
authorization-grant-type: client_credentials
scope: read
provider:
idp:
authorization-uri: myidp/authorization.oauth2
token-uri: myidp/token.oauth2
user-info-uri: myidp/userinfo.openid
user-name-attribute: name
And beans,
@Bean
WebClient webClient(ClientRegistrationRepository clientRegistrations,
OAuth2AuthorizedClientRepository authorizedClients) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServletOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations, authorizedClients);
// (optional) explicitly opt into using the oauth2Login to provide an access token implicitly
// oauth.setDefaultOAuth2AuthorizedClient(true);
// (optional) set a default ClientRegistration.registrationId
// oauth.setDefaultClientRegistrationId("client-registration-id");
return WebClient.builder().apply(oauth.oauth2Configuration()).build();
}
and autowiring the webclient to a test and calling it like so,
webClient.get().uri("http://localhost:" + port + "/web/it")
.attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("idp")).retrieve()
.bodyToMono(String.class).block();
It is my assumption the exchange function would either get an access token if available, or do a call to get a new one from the IDP. However it will always fail as the HttpSessionOAuth2AuthorizedClientRepository as the HttpServletRequest is null.
With the overall test looking like, this feeds into an autoconfiguration to configure some beans for an IDP provider.
@SpringBootTest(classes = WebITApplication.class,
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ExtendWith(SpringExtension.class)
@ActiveProfiles("web-it")
class WebJwtIt {
@LocalServerPort
private int port;
@Autowired
private WebClient webClient;
@Test
void testIdpJwt() {
String response = webClient.get().uri("http://localhost:" + port + "/web/it")
.attributes(ServletOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("ping")).retrieve()
.bodyToMono(String.class).block();
assertThat(response).isEqualTo("pass");
}
@RestController
@SpringBootApplication
@ImportAutoConfiguration(IdpAutoConfiguration.class)
static class WebITApplication implements IdpSecurityAdapter {
@Bean
WebClient webClient(ClientRegistrationRepository clientRegistrations,
OAuth2AuthorizedClientRepository authorizedClients) {
ServletOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServletOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations, authorizedClients);
// (optional) explicitly opt into using the oauth2Login to provide an access token implicitly
// oauth.setDefaultOAuth2AuthorizedClient(true);
// (optional) set a default ClientRegistration.registrationId
// oauth.setDefaultClientRegistrationId("client-registration-id");
return WebClient.builder().apply(oauth.oauth2Configuration()).build();
}
public static void main(String args[]) {
new SpringApplicationBuilder().profiles("web-it").build().run(WebITApplication.class, args);
}
@GetMapping
public String secured() {
return "secured";
}
@GetMapping("/web/it")
public String securedOne() {
return "pass";
}
@Override
public void configure(final HttpSecurity httpSecurity) throws IdpSecurityAdapterException {
try {
httpSecurity.oauth2Client();
} catch (Exception e) {
throw new IdpSecurityAdapterException("Failed to Configure Oauth2Client", e);
}
}
@Override
public IdpProvider getIdpProvider() {
return IdpProvider.MyIdp;
}
}
Is there anyway for a webclient to get the token for me and add it to the request? I know this was possible with the spring-security-oauth:OAuthRestTemplate and reading the documentation I thought it was possible with a web client.