J'essaie de créer une application REST Spring Boot qui doit effectuer un appel REST distant vers une autre application protégée par OAuth2.
La première application utilise le Reactive WebClient pour faire l'appel à la deuxième application REST OAuth2. J'ai configuré le WebClient avec grant_type "client_credentials".
application.yml
spring:
security:
oauth2:
client:
provider:
client-registration-id:
token-uri: http://localhost:8080/oauth/token
registration:
client-registration-id:
authorization-grant-type: client_credentials
client-id: public
client-secret: test
client-authentication-method: post
scope: myscope
@Configuration
public class WebClientConfig {
@Bean
WebClient webClient(ReactiveClientRegistrationRepository clientRegistrations) {
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(
clientRegistrations, new UnAuthenticatedServerOAuth2AuthorizedClientRepository());
oauth.setDefaultClientRegistrationId("client-registration-id");
return WebClient.builder().filter(oauth).build();
}
}
@Component
public class WebClientChronJob {
Logger logger = LoggerFactory.getLogger(WebClientChronJob.class);
@Autowired
private WebClient webClient;
@Scheduled(fixedRate = 5000)
public void logResourceServiceResponse() {
webClient.get()
.uri("http://localhost:8080/test")
.retrieve()
.bodyToMono(String.class)
.map(string -> "RESPONSE: " + string)
.subscribe(logger::info);
}
}
Selon l'article de ce lien Baeldung Spring Webclient Oauth2 la deuxième fois que le WebClientChronJob s'exécute, l'application doit demander la ressource sans demander de jeton au préalable puisque le dernier jeton n'a pas expiré. Malheureusement, en activant les journaux de débogage, j'ai remarqué le contraire : chaque fois que le job demande la ressource, il demande un nouveau jeton. Veuillez me faire savoir si quelque chose manque dans la configuration ou le code.
Netty started on port(s): 8082
Started MyApp in 2.242 seconds (JVM running for 2.717)
HTTP POST http://localhost:8080/oauth/token
Writing form fields [grant_type, scope, client_id, client_secret] (content masked)
Response 200 OK
Decoded [{access_token=nrLr7bHpV0aqr5cQNhv0NjJYvVv3bv, token_type=Bearer, expires_in=86400, scope=rw:profile (truncated)...]
Cancel signal (to close connection)
HTTP GET http://localhost:8080/test
Response 200 OK
Decoded "{"status":{"description":"ok","success":true},"result":[]}"
ESPONSE: {"status":{"description":"ok","success":true},"result":[]}
HTTP POST http://localhost:8080/oauth/token
Writing form fields [grant_type, scope, client_id, client_secret] (content masked)
Response 200 OK
Decoded [{access_token=CsOxziw6W6J7IoqA8EiF4clhiwVJ8m, token_type=Bearer, expires_in=86400, scope=rw:profile (truncated)...]
Cancel signal (to close connection)
HTTP GET http://localhost:8080/test
Response 200 OK
Decoded "{"status":{"description":"ok","success":true},"result":[]}"
ESPONSE: {"status":{"description":"ok","success":true},"result":[]}
Ci-dessous les seules dépendances que j'ai dans le 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-oauth2-client</artifactId>
</dependency>