【问题标题】:Unable to validate access token signature obtained from Azure AD in order to secure Web API无法验证从 Azure AD 获得的访问令牌签名以保护 Web API
【发布时间】:2019-08-10 08:15:09
【问题描述】:

我正在尝试使用隐式流使用 Azure Ad 保护我的 Web api (.net core 2.2)。

我使用 Azure 门户 > Azure Active Directory > 应用程序注册 > 新应用程序注册在 Azure AD 中注册了我的应用程序:

名称 = MyWebApi

应用程序类型 = Web 应用程序/API

登录网址 = http://localhost:55000

创建此应用后,我打开其 Manifest 文件并将 oauth2AllowImplicitFlowfalse 更改为 true

这就是我在 azure 门户中为应用注册所做的一切。

然后我从我的 chrome 浏览器手动调用以下 URL 以获取 access_token:

https://login.microsoftonline.com/MY-AD-TENANT-GUID/oauth2/v2.0/authorize?client_id=MY-REGISTERED-APP-GUID&response_type=token&redirect_uri=http%3A%2F%2Flocalhost%3A55000&scope=openid&response_mode=fragment

调用上述url得到的响应是:

http://localhost:55000/#access_token=MY-ACCESS-TOKEN&token_type=Bearer&expires_in=3600&scope=profile+openid+email+00000003-0000-0000-c000-000000000000%2fUser.Read&session_state=b2be972a-cfbc-49f1-bfc0-6c93f6c87d02

当我将授权标头中的 MY-ACCESS-TOKEN 作为不记名令牌传递给我的 Web API(.net 核心 2.2)时,我收到以下异常:

Microsoft.IdentityModel.Tokens.SecurityTokenInvalidSignatureException:IDX10511:签名验证失败。尝试的密钥:'Microsoft.IdentityModel.Tokens.X509SecurityKey,KeyId:N-lC0n-9DALqwhuHYnHQ63GeCXc'。

然后我尝试手动验证签名:

当我将 MY-ACCESS-TOKEN 粘贴到 https://jwt.io/ 时,标题是:

{

  "typ": "JWT",

  "nonce": "AQABAAAAAACEfexXxjamQb3OeGQ4Gugvm6YdOT-bkA0IPllKMt06-J8If5AQ075TVCav94X_ZYcEYKaPneqdJcqYry-Z4XjX0eMN_fiJX_8wXe9D2b6eRiAA",

  "alg": "RS256",

  "x5t": "N-lC0n-9DALqwhuHYnHQ63GeCXc",

  "kid": "N-lC0n-9DALqwhuHYnHQ63GeCXc"

}

然后我去这个 URL 获取孩子的公钥:N-lC0n-9DALqwhuHYnHQ63GeCXc

https://login.microsoftonline.com/common/discovery/keys

然后我将以下内容作为公钥粘贴到 jwt.io 上以验证令牌签名:

-----BEGIN CERTIFICATE-----

OBTAINED-PUBLIC-KEY-FROM-THE-ABOVE-URL-HERE

-----END CERTIFICATE-----

我又得到无效签名

我去过这个帖子:https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/issues/609,但我不确定为什么我的令牌标头有 nonce 值,或者这对我来说是否是个问题。

有什么想法我在这里做错了吗?

【问题讨论】:

  • 我看到您返回的访问令牌还包括 Microsoft Graph API 的范围。我认为这就是 Nonce 也出现的原因......并且当访问令牌意味着对于 Microsoft Graph,您将无法验证它。特别是 00000003-0000-0000-c000-000000000000/User.Read 范围。其中 00000003-0000-0000-c000-000000000000 是 Microsoft Graph API 的资源 ID。
  • 任何想法为什么我得到 Microsoft Graph 的范围?我没有在我的请求中请求它。
  • 在我看来,您应该更改您的应用程序以获取 API 的访问令牌。因为目前你没有指定你想要的 API。您可以将 API 注册为应用程序,对其定义 OAuth 权限,并将权限分配给获取令牌的前端应用程序。
  • 那是最终的计划,但概念还是一样的。我已经为 API 创建了应用程序注册,并且在从 azure AD 获取其访问令牌后尝试访问该 API。问题是我猜与随机数有关,我不确定为什么我的天蓝色广告令牌在我不请求 Microsoft 图形范围时包含随机数。
  • 很高兴看到您已经很清楚注册 API 和您所说的最终计划。另一件需要注意的事情..您从常规 Azure 门户注册了应用程序(因此默认情况下它会接受 v1 令牌)..但是您正在使用 v2 端点来获取令牌..并且您没有指定您想要的 API令牌,端点正在向您返回注册应用程序时静态定义的所有权限的令牌。我认为您的应用注册可能在当前所需权限下选择了Microsoft GraphUser.Read

标签: oauth-2.0 jwt azure-active-directory openid-connect


【解决方案1】:

我试过这个,效果很好。

请求网址:

https://login.microsoftonline.com/tenant-name/oauth2/v2.0/authorize?client_id=application_id&response_type=token&redirect_uri=https://snv2app.azurewebsites.net&scope=api://f3d966c0-517e-4e13-a5bb-9777a916b1a0/User.read openid&response_mode=fragment

当我得到access_token后,我在jwt.io中解析并输入公钥,得到结果:

【讨论】:

  • Whats api://f3d966c0-517e-4e13-a5bb-9777a916b1a0/User.read 在范围内?
  • api://f3d966c0-517e-4e13-a5bb-9777a916b1a0 是我的api和相关权限。
  • 确实是问题所在,我的作用域不包含 API 的 URI,将其传递到作用域并没有返回 nonce 值,因此我能够验证签名。感谢您的帮助。
【解决方案2】:

这里发生的是您收到的令牌是 userInfo 端点的 access_token。观众是图。图的令牌已以特殊方式修改,因此必须在验证签名之前对其进行转换。这允许图将令牌转发到下游(在转换之后),而不必担心会发生转发攻击。

验证是否'aud == graph'。

【讨论】:

  • 我遇到了同样的麻烦,正在使用访问令牌使用 JWT.io 站点对其进行验证,但失败了,您的评论帮助我查看是否可以验证 idToken 并通过验证!但是知道如何验证访问令牌吗?我正在使用 MSAL.js 库,它使用图形范围的参数调用 acquireTokenSilent 来获取访问令牌。那么,这个graph access token有没有办法验证呢?
  • @Maverick 你想对令牌进行什么验证? Graph 将在收到令牌时验证令牌。
  • 我想获取他们所属的用户角色和组
  • 您可以将令牌发送到图形以获取该信息。很难说该令牌中的内容或图形如何使用它。
猜你喜欢
  • 1970-01-01
  • 2021-08-10
  • 2019-11-14
  • 1970-01-01
  • 2017-05-19
  • 1970-01-01
  • 2022-11-01
  • 1970-01-01
  • 2020-01-12
相关资源
最近更新 更多