【发布时间】:2021-07-03 17:14:06
【问题描述】:
以下代码将获取 20 台设备,并将使用在线服务中的一些数据。
为了使用在线服务,WebClient 需要获取访问令牌(authorization-grant-type=client_credentials)
spring.security.oauth2.client.registration.web.client-id=xxxx
spring.security.oauth2.client.registration.web.client-secret=xxxx
spring.security.oauth2.client.registration.web.scope=xxxx
spring.security.oauth2.client.registration.web.authorization-grant-type=client_credentials
spring.security.oauth2.client.provider.web.token-uri=https://xxxx
配置:
@Configuration
public class Config {
@Autowired
public ClientRegistrationRepository clientRegistrationRepository;
@Bean
public WebClient webClient(ExchangeFilterFunction getOAuth2FilterFunction) {
logger.info("** start webClient **");
return WebClient.builder().filter(getOAuth2FilterFunction).build();
}
@Bean
public ExchangeFilterFunction getOAuth2FilterFunction(ReactiveClientRegistrationRepository clientRegistrationRepository) {
logger.info("** start getOAuth2FilterFunction **");
InMemoryReactiveOAuth2AuthorizedClientService authorizedClientService = new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrationRepository);
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(new ClientCredentialsReactiveOAuth2AuthorizedClientProvider());
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth2FilterFunction = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth2FilterFunction.setDefaultClientRegistrationId("web");
return oauth2FilterFunction;
}
@Bean
public ReactiveClientRegistrationRepository clientRegistrations() {
logger.info("** start clientRegistrations **");
ClientRegistration clientRegistration = clientRegistrationRepository.findByRegistrationId("web");
return new InMemoryReactiveClientRegistrationRepository(clientRegistration);
}
网络客户端:
private void getData(List<Device> initlist) {
logger.info("** start getDeviceData **");
List<Mono<DeviceDto>> jsonDeviceList = initlist.stream()
.map(device -> webClient.post().uri(infoUri)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.body(Mono.just(device.getMacAddress()),String.class)
.attributes(ServerOAuth2AuthorizedClientExchangeFilterFunction.clientRegistrationId("web"))
.retrieve()
.bodyToMono(DeviceDto.class))
.collect(Collectors.toList());
ObjectMapper mapper = new ObjectMapper();
Flux<DeviceDto> mergedMonos = Flux.fromIterable(jsonDeviceList).flatMapSequential(Function.identity());
mergedMonos.map(device -> mapper.valueToTree(device)).collectList().subscribe(list -> {
generateCsv(list);
});
}
问题在于,对于每个服务请求,都会有来自身份验证服务器的等效访问令牌请求。因此,对于列表中的所有 20 台设备,WebClient 将请求访问令牌 20 次。
如何将其更改为只有一个呼叫而不是 20 个?
谢谢
【问题讨论】:
-
你试过什么?
-
我可以通过DEBUG模式看到有20个auth调用
-
这不是我的问题,我的问题是,您编写了哪些代码来尝试解决问题。
-
无论您在帖子中看到什么
-
您已经编写了一个拦截过滤器,它将拦截每个调用 oauth 服务器的请求。 ofc 它将为每个请求执行一个请求。如果您不想这样做,请先执行一个请求,然后再执行 20 个请求.... 使用常规 Web 客户端。
标签: java spring-security spring-webflux spring-security-oauth2