OAuth2 Client as Application module
Example of application module, which uses OAuth2 client with client credentials grant flow. Example of such applications are batch applications executing tasks, which needs to access API of other modules or systems.
Application utilizes the Spring Security OAuth2 Client, which supports: * logging-in users in using OAuth 2.0 or OpenID Connect 1.0 * obtaining an access token for application in order to access an API
The application also utilizes the Spring WebClient with the Spring Security extension, which adds capabilities as injection of access tokens into HTTP requests (Authorized WebClient).
-
First add required dependencies into build.gradle file. Spring Boot provides convenient way with starter:
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' -
You need to register OAuth2 client with application. The Auth Server defines client with name/id app-client, so you can use it. This client is configured to support Client Credentials OAuth2 grant which is required by this example. There is
springprovider configured, which requires OAuth2 token endpoint URI. Thenspringprovider is used in client registration config. Add following configuration into application.yaml file:spring: security: oauth2: client: registration: # Required for login app-client: provider: spring client-id: app-client client-secret: secret client-authentication-method: client_secret_post authorization-grant-type: client_credentials redirect-uri: "http://localhost:8080/login/oauth2/code/app-client" scope: openid client-name: Spring provider: spring: token-uri: http://auth-server:9000/oauth2/token -
The configuration class WebClientConfiguration is used to define required client components. This lab utilizes WebClient from reactive webflux project. You need to plug-in OAuth2 client, which will automatically authorize with Auth Server. Then it adds required client filter, which includes valid access token in o client request sent to Resource Server. Spring Security includes OAuth2AuthorizedClientManager, which maintains register of defined OAuth2 clients and also authorized clients. This manager is used in filter function added to WebClient. The above is achieved by following configuration:
@Bean WebClient webClient(OAuth2AuthorizedClientManager authorizedClientManager) { ServletOAuth2AuthorizedClientExchangeFilterFunction oauth2Client = new ServletOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); return WebClient.builder() .filter(oauth2Client) .build(); } @Bean OAuth2AuthorizedClientManager authorizedClientManager(ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientService authorizedClientService) { OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder .builder() .clientCredentials() .build(); AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientService); authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); return authorizedClientManager; }Notice the ServletOAuth2AuthorizedClientExchangeFilterFunction added as filter function into WebClient.
-
The WebClient is used by the ClientService service invoked by scheduled job. ClientService calls Resource Server via API. You need to add OAuth2 client
app-clientinto WebClient execution sequence via attributes() function:public void callHallo() { webClient.get() .uri("http://localhost:8090/api/hello") .attributes(clientRegistrationId("app-client")) .retrieve() .bodyToMono(String.class) .subscribe(LOG::info); } -
Now start application and check console. The Auth Server and Resource Server must be up and running.