Azure AD:访问令牌中缺少角色声明

Posted

技术标签:

【中文标题】Azure AD:访问令牌中缺少角色声明【英文标题】:Azure AD: Roles claims missing in access token 【发布时间】:2018-02-07 23:06:16 【问题描述】:

对于我的应用程序,我希望用户能够使用他们的 Azure 帐户登录(单点登录)。我还需要一个访问令牌来访问受保护的后端。 所以我可以同时获得id_tokenaccess_token,并请求此网址:

https://login.microsoftonline.com/MY_TENANT_ID/oauth2/authorize?response_type=id_token+token&client_id=MY_CLIENT_ID&state=SOME_STATE&redirect_uri=MY_REDIRECT_URI&scope=openid profile&resource=MY_CLIENT_ID&nonce=SOME_NONCE

这基本上可行,但我也想在访问令牌(和 id 令牌)中拥有角色,但我收到的令牌中不包含角色

当我使用此 Url 仅获取 id_token 时,包含角色声明

https://login.microsoftonline.com/MY_TENANT_ID/oauth2/authorize?response_type=id_token&client_id=MY_CLIENT_ID&state=SOME_STATE&redirect_uri=MY_REDIRECT_URI&scope=openid profile&nonce=SOME_NONCE

不同之处在于我只请求id_token 而不是token,我省略了resource 参数。

我的问题是:为什么角色声明不包含在第一个请求的令牌中?我有哪些选择来获得id_tokenaccess_token 以及角色声明?

编辑: 这就是 approles 在应用清单中的定义方式:


  "appId": "MY_CLIENT_ID",
  "appRoles": [
    
      "allowedMemberTypes": [
        "User"
      ],
      "displayName": "Admin",
      "id": "c200e304-fff3-49f1-a4df-e406741ea690",
      "isEnabled": true,
      "description": "Bla bla",
      "value": "admin"
    ,
    
      "allowedMemberTypes": [
        "User"
      ],
      "displayName": "Reader",
      "id": "c534f351-b343-48d0-9dd7-ecb4c5cb402d",
      "isEnabled": true,
      "description": "Bla bla",
      "value": "reader"
    
  ],
  "availableToOtherTenants": false,
  ...

【问题讨论】:

我从未见过实际使用过token 参数。您是否尝试过对授权码授予流程做同样的事情? IE。 response_type=id_token+code,然后将代码交换为访问令牌。 我会试一试的。那么你认为这是一个错误吗? 不确定,不过看起来很奇怪。 好的,我试过response_type=id_token+code。通过代码,我从令牌端点获取了令牌,它给了我 access_token、refresh_token 和 id_token。 access_tokenid_token 都再次缺少角色声明。 :( 您能否补充一下您在问题中如何定义您的角色?例如清单的一部分。 【参考方案1】:

我也可以重现该问题。不确定这是一个错误还是设计使然,我发现这个问题仅在我们为应用程序自身获取令牌时发生。例如,如果我们将资源替换为 Azure AD Graph,则角色声明可以在 id_token 中成功发出。

作为此问题的解决方法,我建议您在第一个请求中获取 id_token。然后您可以使用 adal 库在 iframe 中获取访问令牌,而无需用户交互,因为用户已经登录。

【讨论】:

感谢您对此进行调查。问题是 - 是的,我会得到带有 id_token 的角色 - 但它们仍然没有附带 access_token,即使单独获取它也是如此。 AFAIK,这种roles 声明不会发送到 access_token。 roles 仅在我们使用包含需要管理员同意的权限的client credentials flow 请求访问令牌时在访问令牌中发出。 据我所知,客户端凭据流不是特定于用户的。那么在 access_token 中怎么会有特定用户的角色呢? 目前没有办法在访问令牌中发出这样的声明。如果您正在开发 Web API,您可以使用 id_token 而不是访问令牌进行身份验证作为一种解决方法。 微软不鼓励使用身份验证令牌进行授权

以上是关于Azure AD:访问令牌中缺少角色声明的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Azure AD MSAL 库将角色包含到访问令牌中

在 Azure AD B2C 中请求令牌时缺少范围“scp”

Azure AD:如何将安全组和应用程序角色都放入访问令牌

从 Azure AD 发出 JWT 令牌中的角色

使用刷新令牌 adal azure AD 静默更新访问令牌

从 URL Azure AD 捕获访问令牌以用于令牌