我可以从 Spring Security Oauth 中检索访问令牌吗?

Posted

技术标签:

【中文标题】我可以从 Spring Security Oauth 中检索访问令牌吗?【英文标题】:Can I retrieve the Access Token from Spring Security Oauth? 【发布时间】:2019-11-12 14:51:12 【问题描述】:

上下文:我正在尝试使用 google 播放列表,现在就列出它们

curl \
  'https://www.googleapis.com/youtube/v3/playlists?part=snippet%2CcontentDetails&maxResults=25&mine=true&key=[YOUR_API_KEY]' \
  --header 'Authorization: Bearer [YOUR_ACCESS_TOKEN]' \
  --header 'Accept: application/json' \
  --compressed

所以我已经用 Spring Boot 2.1.6 设置了谷歌登录,如下(它有效)

spring.security.oauth2.client.registration.google.client-id=...
spring.security.oauth2.client.registration.google.client-secret=...
spring.security.oauth2.client.registration.google.redirect-uri=http://localhost:8080/login/oauth2/code/google
spring.security.oauth2.client.provider.google.token-uri=https://oauth2.googleapis.com/token
spring.security.oauth2.client.provider.google.authorization-uri=https://accounts.google.com/o/oauth2/v2/auth
spring.security.oauth2.client.provider.google.user-info-uri=https://openidconnect.googleapis.com/v1/userinfo
spring.security.oauth2.client.provider.google.jwk-set-uri=https://www.googleapis.com/oauth2/v3/certs
spring.security.oauth2.client.provider.google.issuer-uri=https://accounts.google.com
spring.security.oauth2.client.registration.google.scope=profile,https://www.googleapis.com/auth/youtube

根据google google docs,我应该在 spring 发出请求期间取回访问/授权令牌。如何检索此令牌,以便进一步调用 youtube 等 API?

【问题讨论】:

您使用的是 Spring Security OAuth 还是 Spring Security 5? @NatFar spring security 5 @xenoterracide - 您是否已经找到任何解决方案? @ManojShevate 是的,我在上游问过,Joe Grandja 从来没有把他的答案发回到这里,而是责备我没有先在这里问......我已经发布了链接。无论如何...我在这里添加了答案。我不记得我是否尝试过。 @ManojShevate 请参阅github.com/spring-projects/spring-security/issues/… 【参考方案1】:

如果 Spring Security 配置为 OAuth 2.0 登录,OAuth2LoginAuthenticationFilter 使用 HttpSessionOAuth2AuthorizedClientRepository(默认情况下)将经过身份验证的用户存储在会话中。虽然很遗憾,Authentication 对象 (OAuth2AuthenticationToken) 没有原始令牌,但您应该能够从保存在会话中的客户端中提取它:

String attributeName = HttpSessionOAuth2AuthorizedClientRepository.class.getName()
                           +  ".AUTHORIZED_CLIENTS";

Map<String, OAuth2AuthorizedClient> authorizedClients = request.getSession()
                                                      .getAttribute(attributeName);

OAuth2AuthorizedClient client = authorizedClients.get("google");

String token = client.getAccessToken().getTokenValue();

虽然这应该可行,但它非常脆弱。希望有另一种解决方案不涉及将自定义实现交换到安全框架中。

【讨论】:

您确定会话中的那个位置吗?也许我没有使用 Spring Security 5,尽管我在类路径上看不到任何版本为 5.x 的 jar。 ``` 实现(enforcedPlatform(“org.springframework.boot:spring-boot-starter-parent:2.1.6.RELEASE”))实现(kotlin(“stdlib”))实现(kotlin(“reflect”))实现( "org.springframework.boot:spring-boot-starter-web") 实现("org.springframework.boot:spring-boot-starter-security") 实现("org.springframework.boot:spring-boot-starter-oauth2 -client") ```【参考方案2】:

来自@jgrandja https://github.com/spring-projects/spring-security/issues/7088#issuecomment-511820737

不,它不会被消灭。您可以通过OAuth2AuthorizedClientRepositoryOAuth2AuthorizedClientService 检索OAuth2AuthorizedClientOAuth2AuthorizedClient 包含 OAuth2AccessToken 和可选的 OAuth2RefreshToken。 请参阅ref doc 了解更多信息。

另外,获取OAuth2AuthorizedClient 的更方便的方法是通过@RegisteredOAuth2AuthorizedClient。

我鼓励您阅读参考文档,因为那里有很多信息可能会回答您的问题。

OAuth 2.0 Client OAuth 2.0 Login

【讨论】:

以上是关于我可以从 Spring Security Oauth 中检索访问令牌吗?的主要内容,如果未能解决你的问题,请参考以下文章

具有密码授予类型的 WebClient 的 Spring Security OAuth 客户端不要求新令牌

在没有 servlet api 的 webflux 项目中使用 OAuth2 和 Spring Security OAuth2 和 reactor netty

获取'无法在grails Spring安全性休息中调用null对象上的方法loadUserByUsername()'

我可以从 Spring Security Oauth 中检索访问令牌吗?

Spring mvc / security:从spring security中排除登录页面

从 Spring Security Expressions 调用静态方法?