【问题标题】:Postman Client Credentials Flow with Azure AD protected ressource带有 Azure AD 保护资源的 Postman 客户端凭据流
【发布时间】:2017-03-31 05:04:09
【问题描述】:

我目前正在使用这个例子:

https://docs.microsoft.com/en-us/azure/active-directory/active-directory-authentication-scenarios#daemon-or-server-application-to-web-api

在 Azure AD 中使用 OAuth 检查客户端凭据流。从理论上讲,该示例可以正常工作。客户端 App 成功与服务器 App 通信,首先从 Azure AD 令牌 url 获取 OAuth 令牌。那里没有问题。但是,我正在尝试使用 Postman 检查客户端凭据流,但我无法使其正常工作。

在 Postman 中,我应该提供 Access Token UrlClient IDClient SecretGrant Type 设置为 客户凭据。使用与https://github.com/Azure-Samples/active-directory-dotnet-daemon 中 Microsoft 示例提供的示例相同的参数,我在尝试访问 Web 服务时收到 401 响应。我认为主要原因是因为在 Postman 中,我无法输入我想要访问的 resource,因此收到的令牌没有“链接”到任何资源,这就是网络授权失败的原因服务器?这可能是原因吗?如果这是原因,那么我应该在服务器上做什么,因为不知何故,邮递员的要求似乎应该是客户端凭据流中有效的要求(我的意思是,不应该提供 resource ,根据 OAuth2 客户端凭据流程,对吗?

这是从 Microsoft 示例下载的示例中 Starup 类的代码

    // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
    public void ConfigureAuth(IAppBuilder app)
    {
        app.UseWindowsAzureActiveDirectoryBearerAuthentication(
            new WindowsAzureActiveDirectoryBearerAuthenticationOptions
            {
                Audience = ConfigurationManager.AppSettings["ida:Audience"],
                Tenant = ConfigurationManager.AppSettings["ida:Tenant"]
            });
    }

ConfigurationManager.AppSettings["ida:Tenant"] 是我的 Azure AD 租户,而 ConfigurationManager.AppSettings["ida:Audience"] 是我需要访问的受保护资源。这两个值都是必需的,如果我不提供 Audience,我会在 .NET Web API 初始化中收到错误。

【问题讨论】:

标签: .net authentication asp.net-web-api oauth-2.0 azure-active-directory


【解决方案1】:

编辑

我认为问题在于 Azure 令牌服务器不接受作为授权标头发送的客户端凭据。例如

Authorization: Basic YmE1NTZlYmItZGY2OS00NjBhLWEwMjItNTI0NWQ0MzA2N2UxOmVxVzlqaXRobXF2cVFiVWY5dmxaWnhZN2wwUzZhQ0pHSkExSGt0eUd3N0W6

但这就是 Postman 的“获取新访问令牌”工具发送它的方式。所以它是行不通的。

如果您查看Microsoft's documentation 并搜索“get a token”,您会看到这意味着应在正文中提供客户端凭据。

POST /common/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded

client_id=535fb089-9ff3-47b6-9bfb-4f1264799865&scope=https%3A%2F%2Fgraph.microsoft.com%2F.default&client_secret=qWgdYAmab0YSkuL1qKv5bPX&grant_type=client_credentials

这很好用,但似乎与Oauth 2.0 spec 相矛盾:

授权服务器必须支持 HTTP Basic 身份验证 用于验证已发布客户端的客户端的方案 密码。

结束编辑

您绝对可以在不提供资源的情况下取回不记名令牌。

请注意,resource 在上一个答案的邮递员 http 正文中甚至没有正确拼写 - 它拼写为 resrource,这就是为什么它的 https://graph.microsoft.com 值被忽略并且与发送的 resource 不匹配回到回复(00000002-0000-0000-c000-000000000000)。虽然很有趣,但它们都与 api 图有关……但这是题外话。

令人困惑的是,向 Oauth 2.0 服务器提供客户端凭据的方式有两种,有些服务器不接受这两种方式!

  • 1 正在添加一个 basic auth 标头,该标头设置为 Base64(ClientId + ":" + ClientSecret)
  • 2 是在请求​​正文中添加 clientId 和 clientSecret。

我想这就是 Oauth 2.0 作为规范而不是协议的问题...... 见-https://www.rfc-editor.org/rfc/rfc6749#section-2.3.1

Postman 的请求令牌 UI(见下图)使用方法 1,但 Azure 身份验证服务器需要方法 2。我知道是因为我运行了 fiddler,并且可以看到请求 postman 放在一起。

如果您手动将客户端凭据放入正文中,例如

grant_type=client_credentials&scope=&client_id=ba556ebb-xxxx9-460a-ax2x-5245d43067e1&client_secret=eqW9jighghghgvlZZxY7l0S6aCJGJA1HktyGw7E=

并且不要使用Basic Auth http 标头。即使提供资源,您也可以取回不记名令牌。

这很好 - 但显然这对您使用邮递员获取和存储您的令牌没有好处!

【讨论】:

  • 我还没有仔细检查这篇文章中的内容,但这是关于为什么 Postman 仍然无法使用它的“获取新访问令牌”对话框系统从 Azure 获取 OAuth2 令牌的第一个合理解释旨在做到这一点。如果这是正确的,它应该可以在邮递员中以某种方式寻址,并且希望有一张票。找了半天也没找到答案。
【解决方案2】:

我认为主要原因是因为在 Postman 中,我无法输入我想要访问的资源,所以接收到的令牌没有“链接”到任何资源,这就是 Web 服务器中授权失败的原因?会不会是这个原因?

你是对的。要通过客户端凭据流获取访问令牌,我们需要在请求中提供资源

你的意思是不能输入资源?资源参数是一个我们可以包含在body中的参数,这里有一个图供大家参考:

并确保 resrouce 的值与用于保护资源的 audience 配置一致。

【讨论】:

  • 是的,当然,如果您直接请求 OAuth2 令牌 URL。问题是我没有向令牌 URL 发出请求,而是向受支持客户端凭据流的 Azure AD 保护的 REST 服务发出请求。在这种情况下,是 Postman 向令牌 URL 发出请求,因为我使用 Postman 的内置授权功能(图片最左侧的授权选项卡),使用 OAuth2 请求令牌失败,因为在 Postman验证对话框,我看不到输入受保护资源的方法。
  • 根据我在 Postman 的 Slack 帐户中收到的响应:在 client_credentials 流程中,client_id 和 client_secret 在 tools.ietf.org/html/rfc6749#section-4.4 中指定的 Authorization 标头中发送,这意味着根据 OAuth 规范,client_id和 client_secret 在 Authorization 标头中传播,而不是您提供的图像(这也是我的理解,因为您的示例工作正常,我在 C# 中创建的测试也是如此,但它们以 Body 形式发送这些参数,而不是在身份验证标头)。我现在有点迷茫。
  • Azure AD 实现 OAuth 2.0 时有点不同,我们在 body 中提供了 require 参数,如上图。并且客户端凭据与您直接将请求发送到令牌端点或从受 Azure AD 保护的 Web API 发送请求相同。但在您的场景中,我们还需要提供令牌以通过授权访问受保护的 Web API。然后在 web api 中,我们可以像在 Postman 中一样构建 Client Credential 流程。有关此流程的更多详细信息,请参阅here
  • 而且我们总是需要在body中指定resource参数。
猜你喜欢
  • 1970-01-01
  • 2020-03-25
  • 2019-12-03
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
  • 1970-01-01
  • 2019-06-16
  • 2020-07-07
相关资源
最近更新 更多