我的Spring Boot客户端应用程序如何访问Spring Security 5中由Google提供的刷新令牌
很简单的问题。远程授权服务器(例如Google(发送了一个刷新令牌,我想使用它。在Spring Security 5中保存和检索它的最佳方式是什么?
这个答案、这个问题和这个外部链接似乎描述了一种自Oauth2在Spring Security 5中成为一级公民以来不再兼容的方法。
上下文:
刷新令牌允许客户端应用程序在用户会话过期后继续访问资源。根据谷歌的文档,刷新令牌应该是持久的:
应用程序应存储刷新令牌以供将来使用,并使用访问令牌访问Google API。
Spring安全性使访问令牌以OAuth2AuthenticationToken的形式广泛可用,但其中不包括刷新令牌。
刷新令牌在OidcUserService
(或覆盖它的类(中也不可用,因为public OidcUser loadUser(OidcUserRequest userRequest)
无权访问刷新令牌。这是一个麻烦,因为用一个自定义类覆盖OidcUserService会很好,该类从其OIDC用户详细信息中创建/检索用户,并同时保存其关联的刷新令牌。
OAuth2LoginAuthenticationFilter
将刷新令牌保存在ClientRegistrationRepository:中
OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
authenticationResult.getClientRegistration(),
oauth2Authentication.getName(),
authenticationResult.getAccessToken(),
authenticationResult.getRefreshToken());
this.authorizedClientRepository.saveAuthorizedClient(authorizedClient, oauth2Authentication, request, response);
默认实现将令牌保留在临时内存中,这不适合分布式应用程序或在重新启动时持久化。
似乎有一个JdbcOauth2AuthorizedClientService
,最近添加了文档,还有一个模式表明它可能有用,但没有提供配置它或使用它检索刷新令牌的示例。
那么,客户端应用程序如何在SpringSecurity5中持久化并访问刷新令牌呢?
JdbcOauth2AuthorizedClientService
确实适合您的用例。它的配置非常简单。首先,您需要将此表添加到数据库中:
CREATE TABLE oauth2_authorized_client (
client_registration_id varchar(100) NOT NULL,
principal_name varchar(200) NOT NULL,
access_token_type varchar(100) NOT NULL,
access_token_value blob NOT NULL,
access_token_issued_at timestamp NOT NULL,
access_token_expires_at timestamp NOT NULL,
access_token_scopes varchar(1000) DEFAULT NULL,
refresh_token_value blob DEFAULT NULL,
refresh_token_issued_at timestamp DEFAULT NULL,
created_at timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL,
PRIMARY KEY (client_registration_id, principal_name)
);
然后,配置JdbcOauth2AuthorizedClientService
bean:
@Bean
public OAuth2AuthorizedClientService oAuth2AuthorizedClientService
(JdbcOperations jdbcOperations, ClientRegistrationRepository clientRegistrationRepository) {
return new JdbcOAuth2AuthorizedClientService(jdbcOperations, clientRegistrationRepository);
}
请注意,当前的实现有一个错误,该错误将在几天后通过spring安全版本5.3.2解决。