Spring boot 为什么在将授权码交换为访问令牌时得到无效令牌响应?(spring boot、oauth2、azure)

Spring boot 为什么在将授权码交换为访问令牌时得到无效令牌响应?(spring boot、oauth2、azure),spring-boot,spring-security,oauth-2.0,azure-active-directory,eclipse-rcp,Spring Boot,Spring Security,Oauth 2.0,Azure Active Directory,Eclipse Rcp,我正在将oauth添加到应用程序中,遇到以下错误: [invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body] 该项目有一个Spring引导后端和一个EclipseRCP前端。我正在尝试使用azure active directory作为授权服务器进行身份验证。到目前为止,我能够在e

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

[invalid_token_response] An error occurred while attempting to retrieve the OAuth 2.0 Access Token Response: 401 Unauthorized: [no body]
该项目有一个Spring引导后端和一个EclipseRCP前端。我正在尝试使用azure active directory作为授权服务器进行身份验证。到目前为止,我能够在eclipse应用程序启动时启动一个浏览器小部件,并通过将浏览器指向来成功完成授权代码请求。完成授权码请求后,浏览器将重定向到并显示上面的错误

来自pom.xml的依赖项 使用具有以下相关依赖项的spring boot构建:

  • spring boot starter web
    v2.2.4
  • azure active directory春季启动启动程序
    v2.2.1
  • spring-security-oauth2-client
    v5.2.1
  • spring-security-oauth2-jose
    v5.2.1
  • spring-security-oauth2-resource-server
    v5.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 弹簧原木 以下是我尝试使用azure AD用户凭据进行身份验证时的完整堆栈跟踪(缩短以满足正文长度要求,授权代码经过ofc审查):

试图修复此错误 我尝试了这个公开问题的所有解决方案,包括在azure门户清单中启用
oauth2AllowImplicitFlow
,但都没有成功

如果我从eclipse浏览器在上打印授权代码并创建一个到azure AD的令牌请求(使用),我将获得一个带有承载令牌的成功响应

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

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


如果您已经阅读了本文,那么非常感谢:)

根据我的测试,我们可以使用以下代码

我的配置文件

spring:
  security:
    oauth2:
      client:
        registration:
           azure:
             client-id: xxx
             client-secret: xxx
             client-name: Azure
             client-authentication-method: basic
             provider: azure-oauth-provider
             scope: openid, https://graph.microsoft.com/user.read, profile
             redirect-uri: http://localhost:8080/login/oauth2/code/azure
             authorization-grant-type: authorization_code

        provider:
            azure-oauth-provider:
              authorization-uri: https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/authorize
              user-info-uri: https://graph.microsoft.com/oidc/userinfo 
              token-uri: https://login.microsoftonline.com/<tenant id>/oauth2/v2.0/token
              jwk-set-uri: https://login.microsoftonline.com/<tenant id>/v2.0/keys
              user-name-attribute: name

azure:
  activedirectory:
    tenant-id: xxx
    active-directory-groups: ***
spring:
安全:
oauth2:
客户:
注册:
蔚蓝:
客户id:xxx
客户机密:xxx
客户名称:Azure
客户端身份验证方法:基本
提供者:azure oauth提供者
范围:openid,https://graph.microsoft.com/user.read轮廓
重定向uri:http://localhost:8080/login/oauth2/code/azure
授权授予类型:授权\ U代码
供应商:
azure oauth提供程序:
授权uri:https://login.microsoftonline.com//oauth2/v2.0/authorize
用户信息uri:https://graph.microsoft.com/oidc/userinfo 
令牌uri:https://login.microsoftonline.com//oauth2/v2.0/token
jwk集uri:https://login.microsoftonline.com//v2.0/keys
用户名属性:name
蔚蓝:
activedirectory:
租户编号:xxx
active directory组:***
WebSecurityConfig.java

@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .oauth2Login()
            .userInfoEndpoint()
            .oidcUserService(oidcUserService);
    }
}
@EnableWebSecurity
@EnableGlobalMethodSecurity(Prespenabled=true)
公共类WebSecurityConfig扩展了WebSecurityConfigureAdapter{
@自动连线
专用OAuth2UserService oidcUserService;
@凌驾
受保护的无效配置(HttpSecurity http)引发异常{
http
.授权请求()
.anyRequest().authenticated()
.及()
.oauth2Login()
.userInfoEndpoint()
.oidcUserService(OIDCUSERVICE);
}
}


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


有关v1的更多信息,请查看如何使oauth2 V2运行

首先,请注意,microsoft V1登录不适用于私人帐户!因此,降级可能不是每个人的选择

要成功配置V2,请执行以下操作: 我建议使用发现文档-即使不使用自动发现,也可以复制粘贴值:

在您的情况下,jwk集合uri的设置与上面的json不同,应该是:

下面是我使用的完整spring
provider.azure
配置密钥:

authorization-uri: "https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize"
token-uri: "https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token"
user-info-uri: "https://graph.microsoft.com/oidc/userinfo"
jwk-set-uri: "https://login.microsoftonline.com/<tenant>/v2.0/keys"
user-name-attribute: "name"
user-info-authentication-method: "header"
授权uri:“https://login.microsoftonline.com//oauth2/v2.0/authorize"
令牌uri:“https://login.microsoftonline.com//oauth2/v2.0/token"
用户信息uri:“https://graph.microsoft.com/oidc/userinfo"
jwk集uri:“https://login.microsoftonline.com//v2.0/keys"
用户名属性:“名称”
用户信息身份验证方法:“头”

使用spring boot v2.1.2和spring security 5.1.3进行测试。

当交换令牌代码时,响应是什么样子的?我在postman中得到的响应如下:{“令牌类型”:“承载者”,“范围”:“配置文件openid电子邮件”,“过期时间”:3599,“外部过期时间”:3599,“访问令牌”:“访问令牌”,“id_令牌”:“id_令牌”}你知道为什么找不到HttpSession吗?我不知道。看看你提到过什么?我注意到无效的\u令牌\u响应只发生在v2 azure端点上,而不发生在v1上,所以我reverted@phil谢谢你的分享。我很高兴知道你的问题已经解决了resolved@phil事实上,如果你把答案和chec贴出来就好了作为记录,我经历了完全相同的问题,并返回到v1端点,这一切都起了作用。
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private OAuth2UserService<OidcUserRequest, OidcUser> oidcUserService;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
            .anyRequest().authenticated()
            .and()
            .oauth2Login()
            .userInfoEndpoint()
            .oidcUserService(oidcUserService);
    }
}
authorization-uri: "https://login.microsoftonline.com/<tenant>/oauth2/v2.0/authorize"
token-uri: "https://login.microsoftonline.com/<tenant>/oauth2/v2.0/token"
user-info-uri: "https://graph.microsoft.com/oidc/userinfo"
jwk-set-uri: "https://login.microsoftonline.com/<tenant>/v2.0/keys"
user-name-attribute: "name"
user-info-authentication-method: "header"