我目前正在使用 Python 开发 Azure Web 应用程序,它使用 Azure AD 身份验证进行站点访问。我想显示当前用户的电子邮件(我计划稍后也将其用于访问层)。我看到了一种通过使用委托 GraphAPI 来获取电子邮件的方法,以获取用户的详细信息。我尝试过以下方法:
authority = f'https://login.microsoftonline.com/{subid}'
scope = ["https://graph.microsoft.com/.default"]
app = ConfidentialClientApplication(
client_id,
authority=authority,
client_credential=client_secret
)
token_response = app.acquire_token_for_client(scopes=scope)
access_token = token_response['access_token']
headers = {
'Authorization': f'Bearer {access_token}'
}
response = requests.get('https://graph.microsoft.com/v1.0/me', headers=headers)
user_data = response.json()
print("~~~~~~~~~~~~~~~~~~~~~~")
for key, value in user_data.items():
print(f'{key}: {value}')
print("~~~~~~~~~~~~~~~~~~~~~~")
但这会返回错误:
error: {'code': 'BadRequest', 'message': '/me request is only valid with delegated authentication flow.', 'innerError': {'date': '2023-10-20T13:05:47', 'request-id': '9b6d8130-5bf6-4711-ba90-14ccaef0b127', 'client-request-id': '9b6d8130-5bf6-4711-ba90-14ccaef0b127'}}
我认为委托可以工作,因为用户需要在 azure 上进行签名和身份验证才能访问该网站,还是我遗漏了某些内容?
任何帮助或替代方法将不胜感激
发生错误的原因是您的代码使用客户端凭据流生成访问令牌以调用
端点,该端点不是 委托 流,因为它不涉及用户交互。/me
当我在我的环境中运行你的代码时,我也遇到了相同的错误,如下所示:
import msal
import requests
authority = f'https://login.microsoftonline.com/tenantId'
scope = ["https://graph.microsoft.com/.default"]
client_id = "appId"
client_secret = "secret"
app = msal.ConfidentialClientApplication(
client_id,
authority=authority,
client_credential=client_secret
)
token_response = app.acquire_token_for_client(scopes=scope)
access_token = token_response['access_token']
headers = {
'Authorization': f'Bearer {access_token}'
}
response = requests.get('https://graph.microsoft.com/v1.0/me', headers=headers)
user_data = response.json()
print("~~~~~~~~~~~~~~~~~~~~~~")
for key, value in user_data.items():
print(f'{key}: {value}')
print("~~~~~~~~~~~~~~~~~~~~~~")
回复:
要解决错误,您需要切换到委托流程,例如授权代码流程、交互流程等...需要用户登录才能生成访问令牌。
就我而言,我通过下面的选项启用使用了交互式流程,并在移动/桌面平台中添加了http://localhost作为重定向URI:
当我运行下面修改后的 python 代码时,它要求我选择一个帐户来登录:
import msal
import requests
authority = f'https://login.microsoftonline.com/tenantId'
scope = ["https://graph.microsoft.com/.default"]
client_id = "appId"
app = msal.PublicClientApplication(
client_id,
authority=authority,
)
token_response = app.acquire_token_interactive(scopes=scope)
access_token = token_response['access_token']
headers = {
'Authorization': f'Bearer {access_token}'
}
response = requests.get('https://graph.microsoft.com/v1.0/me', headers=headers)
user_data = response.json()
print("~~~~~~~~~~~~~~~~~~~~~~")
for key, value in user_data.items():
print(f'{key}: {value}')
print("~~~~~~~~~~~~~~~~~~~~~~")
登录时,用户将看到同意屏幕以接受如下权限:
接受同意后,我在输出控制台中成功获得了包含登录用户详细信息的响应,如下所示: