我正在构建一个托管在 Azure 中的 python Flask Web 应用程序,该应用程序将图片存储在 blob 文件中,同时将有关该图片的信息存储在 PostgreSQL 灵活服务器的 Azure 数据库中。
用户通过B2C用户流程注册/登录,用户信息保存在B2C租户页面的用户选项卡中。
在信息数据库中,字段之一是“user_email”。我的想法是,我从 B2C 租户获取用户电子邮件,并将其连同与 blob 数据库中的图片相关的所有其他信息发送到数据库。
我尝试过使用 MS graph API:
msal_authority = f"https://login.microsoftonline.com/{tenant_id}"
msal_scope = ["https://graph.microsoft.com/.default"]
msal_app = ConfidentialClientApplication(
client_id=client_id,
client_credential=client_secret,
authority=msal_authority,
)
result = msal_app.acquire_token_silent(
scopes=msal_scope,
account=None,
)
if not result:
result = msal_app.acquire_token_for_client(scopes=msal_scope)
if "access_token" in result:
access_token = result["access_token"]
else:
raise Exception("No Access Token found")
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json",
}
response = requests.get(
url="https://graph.microsoft.com/v1.0/users",
headers=headers,
)
app.logger.debug(json.dumps(response.json(), indent=4))
但是,我收到错误:“ClientAuthenticationError:当前凭证未配置为从租户获取令牌:12345678910”,但租户 id '12345678910”不是 B2C 租户的租户 id,而是B2C租户所在的主目录。我在代码前面设置环境变量(例如客户端id和客户端密钥)时将b2c租户id设置为租户id。
尝试从主目录获取令牌是否正常?我本以为一旦用户登录并在 b2c 租户中“活动”,就不需要与主目录进行身份验证交互。是否需要进行配置以允许 B2C 租户从主目录获取令牌,或者我是否滥用了图形 API 并且正在与主目录而不是 B2C 目录进行交互?
要检索 Azure B2C 租户用户,请在 Azure AD B2C 租户中创建应用程序并添加
User.Read.All
应用程序类型 API 权限:
并使用以下代码获取 Azure AD B2C 租户用户列表及其邮件 ID:
import requests
import json
from msal import ConfidentialClientApplication
client_id = "ClientIDofB2CApp"
client_secret = "ClientSecret"
tenant_id = "TenantIDOfB2C"
authority = f"https://login.microsoftonline.com/{tenant_id}"
app = ConfidentialClientApplication(
client_id=client_id,
client_credential=client_secret,
authority=authority
)
scopes = ["https://graph.microsoft.com/.default"]
result = app.acquire_token_for_client(scopes=scopes)
access_token = result["access_token"]
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
response = requests.get(
url="https://graph.microsoft.com/v1.0/users",
headers=headers
)
if response.status_code == 200:
users = response.json()["value"]
for user in users:
print(user["userPrincipalName"])
else:
raise Exception("Failed to fetch users from Microsoft Graph API")
请注意:如果您想检索登录用户的详细信息,则需要使用委托流程。
向 Azure AD B2C 应用程序授予
User.Read
委派 API 权限。
http://localhost:60276
配置为重定向 URL。使用以下代码:
import msal
import requests
import json
app = msal.PublicClientApplication(
"AzureADB2CappID",
authority="https://login.microsoftonline.com/AzureADB2CTenantID",
client_credential=None
)
scopes = ["https://graph.microsoft.com/.default"]
result = app.acquire_token_interactive(scopes=scopes)
if "access_token" in result:
access_token = result["access_token"]
else:
error_message = result.get("error_description", "No Access Token found")
raise Exception(error_message)
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
response = requests.get(
url="https://graph.microsoft.com/v1.0/me",
headers=headers
)
if response.status_code == 200:
user_details = response.json()
print(json.dumps(user_details, indent=4))
else:
raise Exception("Failed to fetch user details from Microsoft Graph API")
如果问题仍然存在,检查以下内容:
https://login.microsoftonline.com/AzureADB2CTenantID