邮递员:“您无权查看此目录或页面”使用承载令牌

Posted

技术标签:

【中文标题】邮递员:“您无权查看此目录或页面”使用承载令牌【英文标题】:POSTMAN: "You do not have permission to view this directory or page" with Bearer Token 【发布时间】:2017-11-04 08:49:58 【问题描述】:

我有一个托管在 HostGator 上的网站,假设它的域是 https://example.com

我还有一个托管在 Azure 上的应用程序,在整个站点(包括 API 组件)上启用了 Active Directory 身份验证,假设它的域是 https://example.azurewebsites.net

目标 -https://example.com 上执行 php 文件(作为 CRON 作业)并首先使用 Azure 的 Active Directory 对文件进行身份验证,然后从 @987654332 中提取数据@ 通过 HTTP GET 调用。

问题 - 显然,仅在没有不记名令牌的情况下调用 API 会导致 401,但我仍然收到 401,即使我传递的内容似乎是一个有效的 Bearer Token。

这就是我所做的:

使用https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-protocols-oauth-code -

我访问了通过 Azure AD 管理门户提供给我的 https://login.microsoftonline.com/tenant_id/oauth2/authorize?response_type=code&client_id=client_id

返回:

https://example.com/?code=really_long_string_of_code

我把这个really_long_string_of_code 作为一个名为code 的正文参数通过邮递员传递,如下所示:

如您所见,它返回了上面看到的令牌 ^。

然后我拿着这个令牌并通过另一个Postman 呼叫:

但问题是,我仍然收到确切的错误消息:

您无权查看此目录或页面。

我觉得我已经尝试了一切。我什至进入了portal.azure 并设置了“允许的令牌受众”:

任何人都知道我可以更改任何设置以允许发生这种呼叫吗?

【问题讨论】:

【参考方案1】:

evilSnobu 已经解释了这个由不正确的观众引起的问题。我想更笼统地解释一下,以帮助理解这个问题。

OAuth 2.0 授权框架中有客户端和资源服务器两个概念(参考rfc6749)。当客户端调用资源服务器时,资源服务器会验证请求中传入的token。例如,它将验证签名、颁发者、客户端 ID、受众等。

客户: 代表受保护资源请求的应用程序 资源所有者及其授权。 “客户”一词确实 不暗示任何特定的实现特征(例如, 应用程序是否在服务器、桌面或其他设备上执行 设备)。

资源服务器: 托管受保护资源的服务器,能够接受 并使用访问令牌响应受保护的资源请求。

在您的场景中,您获得了 Azure AD Graph (https://graph.windows.net) 的 access_token。但是,您在门户中配置的受众与 access_token 中的 aud 声明不匹配。要解决此问题,我们可以将在 Azure AD 中注册的应用用作客户端和资源。如果是这样,我们需要使用 Application ID 而不是 App ID URI 来获取访问令牌。并将此值配置为 Azure 门户上的 ALLOWED TOKEN AUDIENCES

或者我们可以只在 Azure AD 中注册两个应用,分别代表客户端应用和资源应用。并使用客户端应用程序获取资源应用程序的令牌。如果是这样,resource 的值应该是资源应用的App ID URI,我们还需要在 Azure 门户上将其配置为 ALLOWED TOKEN AUDIENCES

【讨论】:

你是对的!我添加了application ID 而不是App ID URI,并将值添加到门户中的ALLOWED TOKEN AUDIENCES,现在一切正常! 你们还没有解开我的斜杠难题 :) aud 是否有斜杠,resource 呢? @evilSnobu 我现在设置代码的方式是没有斜杠 - 似乎工作得很好! 我遇到了完全相同的问题,在我的情况下,即使使用快速配置(在应用服务中),我只是将范围更改为应用 ID,一切正常(不触及允许的令牌受众) .【参考方案2】:

Allowed Token Audiences中删除尾部斜杠,例如:

https://example.com
http://example.com

..or was 相反..嗯..

401 Unauthorized 当一切看起来正确时,通常在观众中是一个尾随斜线。有时你需要一个,有时你不需要。它应该与您或您的中间件在应用程序代码中定义为有效受众的任何内容相匹配。您还可以使用应用 GUID(应用程序 ID)作为受众。

另外,您似乎将graph.windows.net 设置为resource,这是故意的吗? 你真的应该open that token and check the contents。受众必须与您的 API 的 URL 相匹配。

我觉得这不是验证 machine2machine 调用的正确方法。您可能应该只使用 TLS mutual authentication 或简单地通过 HTTPS 在标头中发送一个硬编码的秘密(是的,就像一个不记名令牌,但没有信任链)。在 API 方面,将其存储在 App Settings 中,然后从相关的环境变量中将其放入您的代码中。在调用应用代码中使用相同的应用设置机制。

您可以使用每 X 天更改一次应用设置的函数应用来轮换此密钥(PowerShell 函数应用具有可用的资源管理 cmdlet,因此您可以使用 SPN 登录 (Add-AzureRmAccount),然后调用 Set-AzureRmWebApp -AppSettings [...]) .

或者,您可以将机密存储在 Azure Key Vault 中,虽然它是一项很棒的服务,但它会为您的用例过度设计。

【讨论】:

以上是关于邮递员:“您无权查看此目录或页面”使用承载令牌的主要内容,如果未能解决你的问题,请参考以下文章

Azure 上托管的 MVC 4 网站说我无权查看目录或页面

如何将承载令牌添加到 HTTP 请求的标头?

laravel 自己的 api 使用来自具有承载令牌的控制器

如何通过具有用户凭证的天蓝色广告生成不记名令牌

为啥我在服务器上没有访问权限?

取回不记名令牌邮递员扑腾