spring-security - 如果在spring webffux中过期或未过期,如何通过检查前一个的生命周期来获取新的访问令牌?
问题描述
我正在开发一个项目,其中服务器仅提供访问令牌而没有刷新令牌以满足某些公司的需求。参考官方文档,如果存在刷新令牌,以下代码将在访问令牌过期时自动刷新。如果不是,它将为每个请求检索一个新请求。
这是最佳代码:
@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(oauth2.oauth2Configuration())
.build();
}
这是我正在使用的代码:
@Configuration
public class OauthEmployeConfig{
/**
** ... String baseUrl, String accessUrl for the access token url
**/
@Bean
public WebClient webClient(UserRegistration userRegistr) {
ClientRequest clientRequest = ClientRequest
.create(HttpMethod.POST, URI.create(accessUrl))
.header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED_VALUE)
.headers(headers -> headers.setBasicAuth(userRegistr.getClientId(), userRegistr.getClientSecret()))
.body(BodyInserters.fromFormData("grant_type", userRegistr.getAuthorizGrantType())
.with("scope", userRegistr.getScope().replaceAll(",", "")))
.build();
return WebClient.builder()
.baseUrl(baseUrl)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.filter((request, next) -> next.exchange(clientRequest)
.flatMap(response -> response.body(org.springframework.security.oauth2.core.web.reactive.function.OAuth2BodyExtractors.oauth2AccessTokenResponse()))
.map(accessToken -> accessToken.getAccessToken().getTokenValue())
.map(token -> setBearer(request, token))
.flatMap(next::exchange))
.filter(logRequest())
.filter(handleResponseError())
.build();
}
private ClientRequest setBearer(ClientRequest request, String token) {
return ClientRequest.from(request)
.header("Authorization", "Bearer " + token).build();
}
private static ExchangeFilterFunction handleResponseError() {
return ExchangeFilterFunction.ofResponseProcessor(
response -> response.statusCode().isError()
? response.bodyToMono(String.class)
.flatMap(errorBody -> Mono.error(new RuntimeException(errorBody, response.statusCode())))
: Mono.just(response));
}
private static ExchangeFilterFunction logRequest() {
return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
clientRequest.headers().forEach((name, values) -> values.forEach(value -> LOG.info("{}={}", name, value)));
return Mono.just(clientRequest);
});
}
}
我想知道是否有一种方法可以获取一次访问令牌并在它未过期时为每个请求保留它,并且在这种情况下我会得到一个新的!
解决方案
推荐阅读
- python - 列的 Dask Dataframe 总和始终返回标量
- javascript - 选中primefaces中的所有复选框
- google-sheets - 如果范围不为空,则填充单元格的公式?
- python - 无法使用 gremlinpython 进行查询
- javascript - 将 Dropzone 文件对象转换为 base64 字符串
- android - 尝试在空对象引用上调用虚拟方法“void android.media.MediaRecorder.setAudioSource(int)”
- amazon-web-services - 如何增加 EC2 (AWS) 的安全组规则限制
- c# - 从特定行中删除列的行
- android - 用户日期和时间的自定义通知
- mysql - Mysql LOAD DATA 截断列