401未授权使用Bearer令牌对Azure API App进行REST调用

时间:2016-06-19 16:21:32

标签: python azure oauth-2.0 jwt adal

我在Azure目录中创建了2个应用程序,1个用于我的API服务器,1个用于我的API客户端。我正在使用Python ADAL库,并且可以使用以下代码成功获取令牌:

tenant_id = "abc123-abc123-abc123"
context = adal.AuthenticationContext('https://login.microsoftonline.com/' + tenant_id)
token = context.acquire_token_with_username_password(
        'https://myapiserver.azurewebsites.net/',
        'myuser',
        'mypassword',
        'my_apiclient_client_id'
        )

然后我尝试使用以下方法向我的API应用发送请求,但不断获取未经授权的':

at = token['accessToken']
id_token = "Bearer {0}".format(at)
response = requests.get('https://myapiserver.azurewebsites.net/', headers={"Authorization": id_token})

我可以使用loginurl中的myuser / mypass成功登录。我还让客户端应用程序访问Azure AD中的服务器应用程序。

3 个答案:

答案 0 :(得分:1)

虽然这个问题是很久以前发布的,但我会尝试提供答案。我偶然发现了问题,因为我们在这里遇到了完全相同的问题。我们可以使用adal库成功获取令牌,但之后我们无法访问获取令牌的资源。

更糟糕的是,我们在.Net中安装了一个简单的控制台应用程序,使用了完全相同的参数,并且它正常运行。我们也可以复制通过.Net应用程序获得的令牌并在我们的Python请求中使用它并且它有效(这一点很明显,但让我们确信问题与我如何组合请求无关)。

问题的来源最终出现在adal python包的oauth2_client中。当我比较.Net发送的实际HTTP请求和python应用程序时,一个微妙的区别是python应用程序发送了一个明确要求api-version=1.0的POST请求。

POST https://login.microsoftonline.com/common//oauth2/token?api-version=1.0 

更改了adal库中oauth2_client.py的以下行后,我可以访问我的资源。

更改

return urlparse('{}?{}'.format(self._token_endpoint, urlencode(parameters)))
方法_create_token_url中的

return urlparse(self._token_endpoint)

我们正在处理一个pull请求来修补github中的库。

答案 1 :(得分:0)

对于当前版本的Azure Python SDK,它支持使用服务主体进行身份验证。它不支持使用ADAL库进行身份验证。也许它会在未来的版本中发布。

有关详细信息,请参阅https://azure-sdk-for-python.readthedocs.io/en/latest/resourcemanagement.html#authentication

有关ADAL可用的平台,另请参阅Azure Active Directory Authentication Libraries

答案 2 :(得分:0)

@Derek, 您可以在Azure门户上设置问题URL吗?如果我设置了错误的问题URL,我可能会收到同样的错误。看来你的代码是对的。 enter image description here

根据我的经验,您需要将您的应用程序添加到Azure AD并获取客户端ID。(我相信您已经这样做了。)然后您可以获取租户ID并输入Azure门户上的问题URL文本框。

注:

在旧门户(manage.windowsazure.com)上,在底部命令栏中,单击“查看端点”,然后复制“联合元数据文档URL”并下载该文档或在浏览器中导航到该文档。 在根EntityDescriptor元素中,应该有一个https://sts.windows.net/形式的entityID属性,后跟一个特定于您的租户的GUID(称为"租户ID")。复制此值 - 它将作为您的颁发者URL。您将配置您的应用程序以便稍后使用它。

我的演示如下:

import adal
import requests

TenantURL='https://login.microsoftonline.com/*******'
context = adal.AuthenticationContext(TenantURL)
RESOURCE = 'http://wi****.azurewebsites.net'
ClientID='****'
ClientSect='7****'
token_response = context.acquire_token_with_client_credentials(
    RESOURCE,
    ClientID,
    ClientSect
)
access_token = token_response.get('accessToken')
print(access_token)
id_token = "Bearer {0}".format(access_token)
response = requests.get(RESOURCE, headers={"Authorization": id_token})
print(response)

请尝试修改它。任何更新,请告诉我。