从 B2C 租户中提取登录用户的电子邮件

问题描述 投票:0回答:1

我正在构建一个托管在 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 azure-active-directory microsoft-graph-api azure-ad-b2c entra
1个回答
0
投票

要检索 Azure B2C 租户用户,请在 Azure AD B2C 租户中创建应用程序并添加

User.Read.All
应用程序类型 API 权限:

enter image description here

并使用以下代码获取 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")

enter image description here

请注意:如果您想检索登录用户的详细信息,则需要使用委托流程。

向 Azure AD B2C 应用程序授予

User.Read
委派 API 权限。

enter image description here

  • 启用以下移动和桌面流程并将
    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")

enter image description here

如果问题仍然存在,检查以下内容:

  • 确保传递 Azure AD B2C 租户 ID。
  • 确保传递Azure B2C应用程序的ClientID。
  • 确保您正在通过有效的授权
    https://login.microsoftonline.com/AzureADB2CTenantID
© www.soinside.com 2019 - 2024. All rights reserved.