如何使用 spring-boot-starter-oauth2-client 执行刷新
How to perform a refresh with spring-boot-starter-oauth2-client
我正在使用 spring-boot-starter-oauth2-client
通过 Google 验证我的用户。这很好用,我可以按预期登录并获得有效访问和刷新令牌。
我正在这样创建访问令牌:
public class TokenServiceImpl implements TokenService {
private final OAuth2AuthorizedClientService clientService;
@Override
public GoogleCredentials credentials() {
final var accessToken = getAccessToken();
return getGoogleCredentials(accessToken);
}
private GoogleCredentials getGoogleCredentials(String accessToken) {
return GoogleCredentials
.newBuilder()
.setAccessToken(new AccessToken(accessToken, null))
.build();
}
private String getAccessToken() {
final var oauthToken = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
return clientService.loadAuthorizedClient(
oauthToken.getAuthorizedClientRegistrationId(),
oauthToken.getName()).getAccessToken().getTokenValue();
}
}
令牌最终在 Google 照片 API 客户端中使用
private PhotosLibraryClient getClient() {
final var settings =
PhotosLibrarySettings
.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(tokenService.credentials()))
.build();
return PhotosLibraryClient.initialize(settings);
}
问题是令牌将在短时间后过期,我想刷新它以使其保持活动状态。
我不确定我可以使用哪种方法模式来执行此操作,而不必编写整个 OAuth 流程(违背 Spring oauth2-client
之类的目的)。
到目前为止,我的应用程序中没有其他 token/security/filter 逻辑。
我只需要手动写出来,还是有其他方法可以做到这一点?
OAuth2AuthorizedClientManager 将负责为您刷新访问令牌,前提是您获得了刷新令牌和访问令牌。 OAuth2AuthorizedClientManager 的文档位于
https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2client
配置 OAuth2AuthorizedClientManager 时,请确保您已在 OAuth2AuthorizedClientProvider 中包含 refreshToken...
@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.authorizationCode()
.refreshToken()
.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager =
new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
// Assuming the `username` and `password` are supplied as `HttpServletRequest` parameters,
// map the `HttpServletRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
authorizedClientManager.setContextAttributesMapper(contextAttributesMapper());
return authorizedClientManager;
}
然后您使用 OAuth2AuthorizedClientManager 获取访问令牌。来自 spring doco 的示例如下...
@Controller
public class OAuth2ClientController {
@Autowired
private OAuth2AuthorizedClientManager authorizedClientManager;
@GetMapping("/")
public String index(Authentication authentication,
HttpServletRequest servletRequest,
HttpServletResponse servletResponse) {
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("okta")
.principal(authentication)
.attributes(attrs -> {
attrs.put(HttpServletRequest.class.getName(), servletRequest);
attrs.put(HttpServletResponse.class.getName(), servletResponse);
})
.build();
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
...
return "index";
}
}
如果当前的accessToken已经过期,这将自动使用之前获得的refreshToken请求一个新的accessToken。
我正在使用 spring-boot-starter-oauth2-client
通过 Google 验证我的用户。这很好用,我可以按预期登录并获得有效访问和刷新令牌。
我正在这样创建访问令牌:
public class TokenServiceImpl implements TokenService {
private final OAuth2AuthorizedClientService clientService;
@Override
public GoogleCredentials credentials() {
final var accessToken = getAccessToken();
return getGoogleCredentials(accessToken);
}
private GoogleCredentials getGoogleCredentials(String accessToken) {
return GoogleCredentials
.newBuilder()
.setAccessToken(new AccessToken(accessToken, null))
.build();
}
private String getAccessToken() {
final var oauthToken = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication();
return clientService.loadAuthorizedClient(
oauthToken.getAuthorizedClientRegistrationId(),
oauthToken.getName()).getAccessToken().getTokenValue();
}
}
令牌最终在 Google 照片 API 客户端中使用
private PhotosLibraryClient getClient() {
final var settings =
PhotosLibrarySettings
.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(tokenService.credentials()))
.build();
return PhotosLibraryClient.initialize(settings);
}
问题是令牌将在短时间后过期,我想刷新它以使其保持活动状态。
我不确定我可以使用哪种方法模式来执行此操作,而不必编写整个 OAuth 流程(违背 Spring oauth2-client
之类的目的)。
到目前为止,我的应用程序中没有其他 token/security/filter 逻辑。
我只需要手动写出来,还是有其他方法可以做到这一点?
OAuth2AuthorizedClientManager 将负责为您刷新访问令牌,前提是您获得了刷新令牌和访问令牌。 OAuth2AuthorizedClientManager 的文档位于
https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2client
配置 OAuth2AuthorizedClientManager 时,请确保您已在 OAuth2AuthorizedClientProvider 中包含 refreshToken...
@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientRepository authorizedClientRepository) {
OAuth2AuthorizedClientProvider authorizedClientProvider =
OAuth2AuthorizedClientProviderBuilder.builder()
.authorizationCode()
.refreshToken()
.build();
DefaultOAuth2AuthorizedClientManager authorizedClientManager =
new DefaultOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientRepository);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
// Assuming the `username` and `password` are supplied as `HttpServletRequest` parameters,
// map the `HttpServletRequest` parameters to `OAuth2AuthorizationContext.getAttributes()`
authorizedClientManager.setContextAttributesMapper(contextAttributesMapper());
return authorizedClientManager;
}
然后您使用 OAuth2AuthorizedClientManager 获取访问令牌。来自 spring doco 的示例如下...
@Controller
public class OAuth2ClientController {
@Autowired
private OAuth2AuthorizedClientManager authorizedClientManager;
@GetMapping("/")
public String index(Authentication authentication,
HttpServletRequest servletRequest,
HttpServletResponse servletResponse) {
OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest.withClientRegistrationId("okta")
.principal(authentication)
.attributes(attrs -> {
attrs.put(HttpServletRequest.class.getName(), servletRequest);
attrs.put(HttpServletResponse.class.getName(), servletResponse);
})
.build();
OAuth2AuthorizedClient authorizedClient = this.authorizedClientManager.authorize(authorizeRequest);
OAuth2AccessToken accessToken = authorizedClient.getAccessToken();
...
return "index";
}
}
如果当前的accessToken已经过期,这将自动使用之前获得的refreshToken请求一个新的accessToken。