Spring Secuity 5:保留并访问 Oauth2 刷新令牌

Nat*_*han 5 spring-security oauth-2.0 spring-security-oauth2 refresh-token

我的 Spring Boot 客户端应用程序如何访问 Spring Security 5 中由 Google 等提供的刷新令牌?

很简单的问题。远程授权服务器(例如Google)发送刷新令牌,我想使用它。在 Spring Security 5 中保存和检索它的最佳方法是什么?

似乎这个答案这个问题这个外部链接描述了一种自从 Oauth2 成为 Spring Security 5 中的一等公民以来不再兼容的方法。

语境:

刷新令牌允许客户端应用程序在用户会话过期后继续访问资源。根据 Google 的文档,刷新令牌应该是持久的:

应用程序应存储刷新令牌以供将来使用,并使用访问令牌来访问 Google API。

Spring security 以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);
Run Code Online (Sandbox Code Playgroud)

默认实现将令牌保留在临时内存中,这不适合分布式应用程序或在重新启动后持续存在。

似乎有一个JdbcOauth2AuthorizedClientService最近添加了文档,以及一个表明它可能有用的架构,但没有提供配置它或使用它来检索刷新令牌的示例。

那么客户端应用程序如何在 Spring Security 5 中持久保存并访问刷新令牌呢?

Sta*_*mir 9

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)
);
Run Code Online (Sandbox Code Playgroud)

然后,配置JdbcOauth2AuthorizedClientServicebean:

@Bean
public OAuth2AuthorizedClientService oAuth2AuthorizedClientService
        (JdbcOperations jdbcOperations, ClientRegistrationRepository clientRegistrationRepository) {
    return new JdbcOAuth2AuthorizedClientService(jdbcOperations, clientRegistrationRepository);
}
Run Code Online (Sandbox Code Playgroud)

请注意,当前的实现有一个错误,该错误将在几天后发布的 spring-security 版本 5.3.2 中得到解决。

  • @Andreas,如果您愿意,您可以使用“JdbcOauth2AuthorizedClientService”,但您也可以使用 JPA 编写自己的服务。如果您不需要自定义行为,我认为最好使用提供的服务。 (2认同)
  • 从 Spring Security 5.4.1(最新版本为 2020 年 10 月)开始,“JdbcOauth2AuthorizedClientService”无法与 Postgres 一起使用(除非您进行其他配置)。我正在尝试修复该问题,请参阅https://github.com/spring-projects/spring-security/pull/9070 (2认同)