【问题标题】:Issue with jwt-bearer authorization grant in Azure ADAzure AD 中的 jwt-bearer 授权问题
【发布时间】:2017-07-02 09:47:41
【问题描述】:

有两个使用不记名令牌身份验证的 ASP.NET Core Web API。这些服务还提供静态文件,这些文件用于同意 API 进入消费应用程序的目录。所以这两个 API 都在 Azure AD 中启用了隐式流。

API2 正在使用 jwt-bearer 授权从 Web API 控制器调用 API1。 API2 有权访问 API1。

来自第三个目录的用户导航到 API2 提供的 SPA。用户被重定向到 Azure AD,登录并同意 API。用户被重定向回 SPA 应用程序,并对 API2 Web API 进行 AJAX 调用。从该控制器,对 API1 进行另一个调用。此调用使用 jwt-bearer 授权 (urn:ietf:params:oauth:grant-type:jwt-bearer) 进行身份验证。

当使用 API2 的客户端凭据和用于调用 API2 的 JWT 令牌进行 AcquireToken 调用时,Azure AD 会响应错误:

Microsoft.IdentityModel.Clients.ActiveDirectory.AdalServiceException: 
AADSTS50027: Invalid JWT token. AADSTS50027: Invalid JWT token. Token format not valid.
Trace ID: 4031717e-aa0c-4432-bbd1-b97a738d3e6f
Correlation ID: 61ae6cd6-6df6-49ee-9145-c16570c28f7b
Timestamp: 2017-02-13 22:44:01Z ---> System.Net.Http.HttpRequestException:  Response status code does not indicate success: 400 (BadRequest). ---> System.Exception: {"error":"invalid_request","error_description":"AADSTS50027: Invalid JWT token. AADSTS50027: Invalid JWT token. Token format not valid.\r\nTrace ID: 4031717e-aa0c-4432-bbd1-b97a738d3e6f\r\nCorrelation ID: 61ae6cd6-6df6-49ee-9145-c16570c28f7b\r\nTimestamp: 2017-02-13 22:44:01Z","error_codes":[50027,50027],"timestamp":"2017-02-13 22:44:01Z","trace_id":"4031717e-aa0c-4432-bbd1-b97a738d3e6f","correlation_id":"61ae6cd6-6df6-49ee-9145-c16570c28f7b"}

谁能告诉我这个错误是什么意思? JWT 令牌本身是正确的,它一定是 Azure AD 不喜欢的内部声明之一。

我在this github repo 中有示例应用程序和重现步骤。

编辑 一张图表可能会阐明我想要做什么。是交互 #3 给了我错误。它使用具有 API2 的 ClientId 和 ClientSecret(或密钥)的 ClientCredential 以及由 directory3 发出的橙色 JWT 令牌,其受众为 API2。

橙色的 JWT 令牌如下所示:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Il9VZ3FYR190TUxkdVNKMVQ4Y2FIeFU3Y090YyIsImtpZCI6Il9VZ3FYR190TUxkdVNKMVQ4Y2FIeFU3Y090YyJ9.eyJhdWQiOiJmOTJjNGI5MS05NTY3LTRjYjgtOTI4MC0yYmFjNDUyYmZjZTEiLCJpc3MiOiJodHRwczovL3N0cy53aW5kb3dzLm5ldC9iYWRiODcyNC1jODExLTRlYjEtOTcwZi04YmI4MzU0NTI0OTEvIiwiaWF0IjoxNDg3MDM1MDI5LCJuYmYiOjE0ODcwMzUwMjksImV4cCI6MTQ4NzAzODkyOSwiYW1yIjpbInB3ZCJdLCJmYW1pbHlfbmFtZSI6Im9uZSIsImdpdmVuX25hbWUiOiJ1c2VyIiwiaXBhZGRyIjoiNzMuMTU3LjExMC4xNjQiLCJuYW1lIjoidXNlciBvbmUiLCJub25jZSI6ImRjOTYwMjkzLWQ0MTItNDFmNy1iMGRhLWYzZWM2NTE1ZTM1YSIsIm9pZCI6IjUzMTE1OTY0LWQwOTMtNGM5NS05MDkzLTg0ZjliNzVmYzNlOSIsInBsYXRmIjoiMyIsInN1YiI6IlVjVFVleGJYd1BWYkZ4aGRDUW9MR25vTkdsZnVQWi1feGtaSndIdU9zM1EiLCJ0aWQiOiJiYWRiODcyNC1jODExLTRlYjEtOTcwZi04YmI4MzU0NTI0OTEiLCJ1bmlxdWVfbmFtZSI6InVzZXIxQHppZWtlbmh1aXNBLm9ubWljcm9zb2Z0LmNvbSIsInVwbiI6InVzZXIxQHppZWtlbmh1aXNBLm9ubWljcm9zb2Z0LmNvbSIsInZlciI6IjEuMCJ9.lhwEL3x3Cu66l-DT-hWmH2DrmCCX2YORGhl4x4_13_lZuUVhMr1OFLUdJ4MZRWG5DJMc8F_SyC4XdDiStwFDaLSI_4L6noXNau3KF6S u3PnqD-FoXoQPtmPPmFrDRZ7nPEtSazEcd9HeSwgVvRZywJRBKQqQQtBGBpS7-Y9kxrO-moUhnBdJJ-gwhu_wxwdEZaOuLs68sZuFaONAunElMKO1iYlC9VHP5xrVzh3ErnRSIp3xmgJNmlbf-9AFUSrjN5UaFjfpGGGJIvoaKbL6rq-J1XNpvKZDFYvoC7RMkqS1KM录-EI7-QCksb3NKhTg6J_bz5uxmjYltjKanWbUg P>

【问题讨论】:

  • 您能否在清除个人信息的情况下共享您的访问令牌?同样在您的消息中,您说“当使用 API2 的客户端凭据和用于调用 API2 的 JWT 令牌进行 AcquireToken 调用时”。这是一个错字吗?您的意思是“调用 API1”?
  • 你检查过这个官方例子吗:github.com/Azure-Samples/…
  • @ShawnTabrizi 感谢您的回复。不,这不是错字。我添加了一个图表来阐明我想要做什么。导致错误的是交互 #3。
  • @juunas 是的,这就是我开始的例子。我添加了一个图表来阐明我想要做什么。
  • 好的,我明白你的情况了。 f92c4b91-9567-4cb8-9280-2bac452bfce1 是 API2 的客户端 ID 对吗?奇怪的一件事是令牌中没有范围。您是否在 API2 的 SPA 中添加了权限要求?

标签: asp.net authentication jwt azure-active-directory


【解决方案1】:

首先,为了让 API2 能够代表用户获取 API1 的令牌,我们需要在 Directory2 中注册 API2 时将 API1 授予 API2,如下所示:

那么由于API1的服务主体也没有在Directory3中创建,所以我们需要先登录API1才能在Directory3上创建API1的服务主体租户。

当用户从 Directory3 登录 SPA 并将请求发送到 API2 时,在代码中您从 Directory2 获取令牌。我们应该从用户的租户(Directory3)那里获取令牌。

在代码中,您使用 clientId 获取令牌,在这种情况下,我们应该使用 ClientCredential,如下所示:

var result = await adal.AcquireTokenAsync(resource, clientCred, userAssertion);

更改后,代码对我来说效果很好。请让我知道它是否有帮助。

另外,你正在开发的场景如下,你可以参考这个link的细节。

【讨论】:

  • 谢谢飞,很好的回答。我有几件事。 we need to grant the API1 to API2 when we register the API2 in the Directory2我可能在最初同意将应用程序定义放入目录2 后更改了它。 we need to sign-in the API1 first to to create the service principal of API1 on Directory3 tenant.这是个问题。我想我可以通过在清单中指定“knownClientApplications”属性来解决这个问题,但这不适用于不同租户中的应用程序。这是即将发布的功能吗? API2 使用 API1 并且品牌不同。
  • in the code you were acquire the token from Directory2. We should acquire the token from the tenant of users(Directory3). 当然,这是有道理的。 you were acquiring the token using the clientId, in this secnario, we should use the ClientCredential 啊,这是一个错误。选择了错误的重载。
  • @MvdD 根据我的理解,该功能可能不会发布。因为应用程序在不同的租户中,通常app1的组织无权更新app2的knownClientApplications。当然,如果您对 Azure AD 有任何想法和反馈,可以通过here 提交。
  • 这个错误是什么意思?据我所知,当我们使用代表 OAuth 2.0 的委托用户身份获取令牌时,第二层 Web 应用程序需要第一个 Web API 提供者,包括用户凭据和第一层 Web 应用程序的凭据,以便第二层 Web API 可以根据那里的信息提供结果。更多细节可以参考this thread
  • Directory1 归我公司所有,directory2 归 ISV 所有。无论如何,他们都需要向我们注册他们的应用程序,因此我们可以使用他们的应用程序 ID 更新 knownClientApplications
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-22
  • 2021-12-20
  • 1970-01-01
  • 2016-12-11
  • 2016-01-03
  • 2017-01-14
  • 2021-02-04
相关资源
最近更新 更多