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

Spring security Spring Secuity 5:持久化并访问Oauth2刷新令牌,spring-security,oauth-2.0,spring-security-oauth2,refresh-token,Spring Security,Oauth 2.0,Spring Security Oauth2,Refresh Token,我的Spring Boot客户端应用程序如何访问Spring Security 5中Google提供的刷新令牌 这个问题很简单。远程授权服务器(例如Google)发送一个刷新令牌,我想使用它。在SpringSecurity5中保存和检索它的最佳方法是什么 看起来,并描述了一种自Oauth2在SpringSecurity5中成为一等公民以来不再兼容的方法 背景: 刷新令牌允许客户端应用程序在用户会话过期后继续访问资源,刷新令牌应该是持久的: 应用程序应该存储刷新令牌以备将来使用,并使用访问令牌访问

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

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

看起来,并描述了一种自Oauth2在SpringSecurity5中成为一等公民以来不再兼容的方法

背景:

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

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

Spring安全性使访问令牌以一种形式广泛可用,但其中不包括刷新令牌

刷新令牌在OidcUserService或重写它的类中也不可用,因为公共OidcUser loadUserOidcUserRequest userRequest无权访问刷新令牌。这是一个令人不快的问题,因为最好使用自定义类覆盖OidcUserService,该自定义类从用户的OIDC用户详细信息创建/检索用户,同时保存其关联的刷新令牌

OAuth2LoginAuthenticationFilter将刷新令牌保存在ClientRegistrationRepository中:

OAuth2AuthorizedClient authorizedClient = new OAuth2AuthorizedClient(
    authenticationResult.getClientRegistration(),
    oauth2Authentication.getName(),
    authenticationResult.getAccessToken(),
    authenticationResult.getRefreshToken());

this.authorizedClientRepository.saveAuthorizedClient(authorizedClient, oauth2Authentication, request, response);
默认实现将令牌保留在临时内存中,这不适用于分布式应用程序或跨重启持久化

似乎有a、with和a可以使用,但没有提供配置它或使用它检索刷新令牌的示例

那么客户端应用程序如何在SpringSecurity5中持久化并访问刷新令牌呢?

JdbcOauth2AuthorizedClientService确实适合您的用例。配置起来非常简单。 首先,您需要将此表添加到数据库中:

创建表oauth2\u授权\u客户端 客户端注册id varchar100不为空, 主体名称varchar200不为空, 访问令牌类型varchar100不为空, 访问\u令牌\u值blob不为空, 在时间戳非空时发出的访问令牌, 访问令牌到期时间戳不为空, 访问\u令牌\u作用域varchar1000默认为空, 刷新\u标记\u值blob默认为空, 在时间戳默认为空时刷新\u令牌\u发出的\u, 在时间戳处创建\u默认当前\u时间戳不为空, 主键客户端\注册\ id、主体\名称 ; 然后,配置JDBCOAuth2AuthorizedClient服务bean:

@豆子 公共OAuth2AuthorizedClient服务OAuth2AuthorizedClient服务 JdbcOperations JdbcOperations,ClientRegistrationRepository ClientRegistrationRepository{ 返回新的JdbcOAuth2AuthorizedClientServicejdbcOperations,clientRegistrationRepository; } 请注意,当前的实现有一个bug,它将在几天后通过spring安全版本5.3.2解决。

JDBCOAuth2AuthorizedClient服务确实适合您的用例。配置起来非常简单。 首先,您需要将此表添加到数据库中:

创建表oauth2\u授权\u客户端 客户端注册id varchar100不为空, 主体名称varchar200不为空, 访问令牌类型varchar100不为空, 访问\u令牌\u值blob不为空, 在时间戳非空时发出的访问令牌, 访问令牌到期时间戳不为空, 访问\u令牌\u作用域varchar1000默认为空, 刷新\u标记\u值blob默认为空, 在时间戳默认为空时刷新\u令牌\u发出的\u, 在时间戳处创建\u默认当前\u时间戳不为空, 主键客户端\注册\ id、主体\名称 ; 然后,配置JDBCOAuth2AuthorizedClient服务bean:

@豆子 公共OAuth2AuthorizedClient服务OAuth2AuthorizedClient服务 JdbcOperations JdbcOperations,ClientRegistrationRepository ClientRegistrationRepository{ 返回新的JdbcOAuth2AuthorizedClientServicejdbcOperations,clientRegistrationRepository; }
请注意,当前的实现有一个bug,该bug将在几天后通过spring security 5.3.2版解决。

您知道这是否只支持某些数据库吗?我正试图将其用于Postgres 12,并获得异常,将令牌值byte[]强制转换为Types.BLOB。使用Types.Blob时,PgPreparedStatement期望数据类型为Blob的instanceof或InputSteam。由于“blob”数据类型在Postgres中不可用,我尝试了OID、BYTEA和TEXT,但问题似乎是在Postgres驱动程序42.2中使用带有字节[]的java.sql.Types.blob会产生冲突。12@JoshCollins它应该支持sqldbs的所有标准特性。如果我目前只在项目中使用Spring JPA,那么您应该在@StavShamir上打开一个问题,我应该仍然使用JdbcOauth2AuthorizedClientService还是使用
JPA?@Andreas如果需要,您可以使用JDBCOAuth2AuthorizedClient服务,但也可以使用JPA编写自己的服务。如果您不需要自定义行为,我认为最好使用提供的服务。非常感谢。您知道这是否仅适用于某些数据库吗?我正试图将其用于Postgres 12,并获得异常,将令牌值byte[]强制转换为Types.BLOB。使用Types.Blob时,PgPreparedStatement期望数据类型为Blob的instanceof或InputSteam。由于“blob”数据类型在Postgres中不可用,我尝试了OID、BYTEA和TEXT,但问题似乎是在Postgres驱动程序42.2中使用带有字节[]的java.sql.Types.blob会产生冲突。12@JoshCollins它应该支持sqldbs的所有标准特性。如果我目前在我的项目中只使用Spring JPA,那么您应该在@StavShamir上打开一个问题,我应该仍然使用JdbcOauth2AuthorizedClientService还是使用JPA编写我自己的服务?@Andreas如果您愿意,您可以使用JdbcOauth2AuthorizedClientService,但您也可以使用JPA编写自己的服务。如果您不需要定制行为,我认为最好使用提供的服务。非常感谢