Spring Security 5:持久化并访问Oauth2刷新令牌



我的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)
);

然后,配置JdbcOauth2AuthorizedClientServicebean:

@Bean
public OAuth2AuthorizedClientService oAuth2AuthorizedClientService
(JdbcOperations jdbcOperations, ClientRegistrationRepository clientRegistrationRepository) {
return new JdbcOAuth2AuthorizedClientService(jdbcOperations, clientRegistrationRepository);
}

请注意,当前的实现有一个错误,该错误将在几天后通过spring安全版本5.3.2解决。

最新更新