为什么在将授权码交换为访问令牌时收到无效的令牌响应?(弹簧靴,OAuth2,天蓝色) [英] Why am I getting an invalid token response when exchanging an authorization code for an access token? (spring boot, oauth2, azure)

查看:27
本文介绍了为什么在将授权码交换为访问令牌时收到无效的令牌响应?(弹簧靴,OAuth2,天蓝色)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将OAuth添加到应用程序中,遇到以下错误:

[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]

该项目有一个Spring Boot后端和一个Eclipse RCP前端。我正在尝试使用Azure Active Directory作为授权服务器进行身份验证。到目前为止,我可以在Eclipse应用程序启动时在中启动浏览器小部件,并通过将浏览器指向http://localhost:8080/oauth2/authorization/azure成功完成授权码请求。完成授权码请求后,浏览器将重定向到http://localhost:8080/login?error并显示上面的错误。

来自pom.xml的依赖项

使用Spring Boot构建,具有以下相关依赖关系:

  • spring-boot-starter-webv2.2.4
  • azure-active-directory-spring-boot-starterv2.2.1
  • spring-security-oauth2-clientv5.2.1
  • spring-security-oauth2-josev5.2.1
  • spring-security-oauth2-resource-serverv5.2.1

来自application.yml的配置

我们支持多个授权服务器,下面是完全配置的Azure客户端:

spring:
  security:
    oauth2:
      client:
        azure:
          client-id: XXX
          client-secret: XXX
          client-name: Microsoft
          scope: openid, https://graph.microsoft.com/user.read, profile
          authorization-grant-type: authorization_code
          redirect-uri: http://localhost:8080/login/oauth2/code/azure
          client-authentication-method: basic
          authentication-method: post
      provider:
        authorization-uri: https://login.microsoftonline.com/XXX/oauth2/v2.0/authorize
        token-uri: https://login.microsoftonline.com/XXX/oauth2/v2.0/token
        user-info-uri: https://graph.microsoft.com/oidc/userinfo
        jwt-set-uri: https://login.microsoftonline.com/dXXX/discovery/v2.0/keys

azure:
   activedirectory:
      tenant-id: XXX
      active-directory-groups: XXX
      allow-telemetry: false

websecurityconfig.java

@Configuration
@EnableConfigurationProperties
@EnableWebSecurity
@Order(1)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                    [...]
                    .anyRequest().authenticated()
                    .and()
                .oauth2ResourceServer(OAuth2ResourceServerConfigurer::jwt)
                .oauth2Login();
    }

    [...]
}

Spring日志

以下是我尝试使用Azure AD用户凭据进行身份验证时的完整堆栈跟踪(缩短以符合正文长度要求&;使用经过授权代码审查的OFC):

2020-02-19 16:10:33.925 DEBUG 19564 --- [qtp148813381-16] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2dd6e039
2020-02-19 16:10:33.925 DEBUG 19564 --- [qtp148813381-16] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-02-19 16:10:33.925 DEBUG 19564 --- [qtp148813381-16] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
2020-02-19 16:10:33.928 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 1 of 16 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 2 of 16 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] w.c.HttpSessionSecurityContextRepository : HttpSession returned null object for SPRING_SECURITY_CONTEXT
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: Session@3a690b15{id=node01xqnw7l82ne041bil2flqsn3vr0,x=node01xqnw7l82ne041bil2flqsn3vr0.node0,req=1,res=true}. A new one will be created.
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 3 of 16 in additional filter chain; firing Filter: 'HeaderWriterFilter'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 4 of 16 in additional filter chain; firing Filter: 'LogoutFilter'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', GET]
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/azure'; against '/logout'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', POST]
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /login/oauth2/code/azure' doesn't match 'POST /logout'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', PUT]
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /login/oauth2/code/azure' doesn't match 'PUT /logout'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.util.matcher.OrRequestMatcher  : Trying to match using Ant [pattern='/logout', DELETE]
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Request 'GET /login/oauth2/code/azure' doesn't match 'DELETE /logout'
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.util.matcher.OrRequestMatcher  : No matches found
2020-02-19 16:10:33.929 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 5 of 16 in additional filter chain; firing Filter: 'OAuth2AuthorizationRequestRedirectFilter'
2020-02-19 16:10:33.930 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/azure'; against '/oauth2/authorization/{registrationId}'
2020-02-19 16:10:33.930 DEBUG 19564 --- [qtp148813381-20] o.s.security.web.FilterChainProxy        : /login/oauth2/code/azure?code=CODE&state=nqsFqxkkNzHJE5knQVdqFLjoPxg1MT_bcn7KzjKSFfU%3d&session_state=3ebe517e-d450-4d49-b8db-8afafe1fa37e at position 6 of 16 in additional filter chain; firing Filter: 'OAuth2LoginAuthenticationFilter'
2020-02-19 16:10:33.930 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.u.matcher.AntPathRequestMatcher  : Checking match of request : '/login/oauth2/code/azure'; against '/login/oauth2/code/*'
2020-02-19 16:10:33.930 DEBUG 19564 --- [qtp148813381-20] .s.o.c.w.OAuth2LoginAuthenticationFilter : Request is to process authentication
2020-02-19 16:10:33.930 DEBUG 19564 --- [qtp148813381-20] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.authentication.OAuth2LoginAuthenticationProvider
2020-02-19 16:10:33.931 DEBUG 19564 --- [qtp148813381-20] o.s.s.authentication.ProviderManager     : Authentication attempt using org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider
2020-02-19 16:10:34.273 DEBUG 19564 --- [qtp148813381-20] .s.a.DefaultAuthenticationEventPublisher : No event was found for the exception org.springframework.security.oauth2.core.OAuth2AuthenticationException
2020-02-19 16:10:34.275 DEBUG 19564 --- [qtp148813381-20] .s.o.c.w.OAuth2LoginAuthenticationFilter : Authentication request failed: org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]

org.springframework.security.oauth2.core.OAuth2AuthenticationException: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]
    at org.springframework.security.oauth2.client.oidc.authentication.OidcAuthorizationCodeAuthenticationProvider.authenticate(OidcAuthorizationCodeAuthenticationProvider.java:148) ~[spring-security-o

2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] .s.o.c.w.OAuth2LoginAuthenticationFilter : Updated SecurityContextHolder to contain null Authentication
2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] .s.o.c.w.OAuth2LoginAuthenticationFilter : Delegating to authentication failure handler org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler@2b0d857b
2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] .a.SimpleUrlAuthenticationFailureHandler : Redirecting to /login?error
2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] o.s.s.web.DefaultRedirectStrategy        : Redirecting to '/login?error'
2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] o.s.s.w.header.writers.HstsHeaderWriter  : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@2dd6e039
2020-02-19 16:10:34.277 DEBUG 19564 --- [qtp148813381-20] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession.
2020-02-19 16:10:34.278 DEBUG 19564 --- [qtp148813381-20] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed
[...]

尝试修复此错误

我已尝试了此未决问题的所有解决方案:https://github.com/microsoft/azure-spring-boot/issues/526,包括在Azure门户清单中启用oauth2AllowImplicitFlow,但均无济于事。

如果我从Eclipse浏览器打印授权码,并创建对Azure AD的令牌请求(使用azure postman collection),我将获得一个具有持有者令牌的成功响应。

那么,为什么我在发出令牌请求时收到未经授权的401?

如果有任何关于如何处理这个问题的建议,我将不胜感激。我正在拼命寻找解决方案,我的下一步是尝试记录Spring令牌请求或使用Wireshark检查它(由于Azure的端点是https,因此必须解密TLS连接)

如果您已经读到这里,谢谢您:)

推荐答案

在@Jim Xu的回答的评论中提到,我通过将Azure端点从v2更改为v1解决了这个问题。这是通过更改端点来实现的,例如 http://login.microsoft.com/common/oauth2/v2.0/authorize变为http://login.microsoft.com/common/oauth2/authorize,如v1 & v2 comparison中所示。

有关v1的更多信息,请查看docs

这篇关于为什么在将授权码交换为访问令牌时收到无效的令牌响应?(弹簧靴,OAuth2,天蓝色)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆