使用 MSAL 获取用户的 Microsoft Entra ID 令牌
重要
本文介绍如何使用 Microsoft 身份验证库 (MSAL) 手动创建 Microsoft Entra ID 令牌。
Databricks 不建议为 Azure Databricks 用户手动创建 Microsoft Entra ID 令牌。 这是因为每个 Microsoft Entra ID 令牌的生存期很短,通常在一小时内就会过期。 在此时间之后,必须手动生成替换 Microsoft Entra ID 令牌。 请改用实现 Databricks 客户端统一身份验证标准的参与工具或 SDK 之一。 这些工具和 SDK 利用 Azure CLI 身份验证,自动生成并替换过期的 Microsoft Entra ID 令牌。
Azure Databricks 托管服务主体直接在 Azure Databricks 中进行管理。 Microsoft Entra ID 托管服务主体在 Microsoft Entra ID 中进行管理,这需要其他权限。 Databricks 建议在大多数用例中使用 Azure Databricks 托管服务主体。 但是,Databricks 建议在必须同时向 Azure Databricks 和其他 Azure 资源进行身份验证的情况下使用 Microsoft Entra ID 托管服务主体。
若要创建 Azure Databricks 托管服务主体,而不是 Microsoft Entra ID 托管服务主体,请参阅管理服务主体。
可使用 Microsoft 身份验证库 (MSAL) 以编程方式获取 Microsoft Entra ID 访问令牌。 本文通过 Python 示例介绍了 MSAL 库的基本用法以及所需的用户输入。
注意
MSAL 会替换 Microsoft Entra ID 身份验证库 (ADAL)。 Microsoft 对 ADAL 的所有支持和开发(包括安全修补程序)已在 2022 年 6 月 30 日结束。 请参阅将应用程序迁移到 Microsoft 身份验证库 (MSAL)。
提示
你可能想要尝试使用 Azure CLI 而不是 MSAL 来为用户获取 Microsoft Entra ID 令牌,因为使用 Azure CLI 所涉及的步骤更少。 请参阅使用 Azure CLI 获取用户的 Microsoft Entra ID 令牌。
还可以在 Microsoft Entra ID 中定义服务主体,并为服务主体而不是用户获取 Microsoft Entra ID 访问令牌。 请参阅获取服务主体的 Microsoft Entra ID 令牌。
在 Azure 门户中配置应用
在 Azure 门户中向 Microsoft Entra ID 终结点注册应用程序。 或者,可以使用已注册的 Microsoft Entra ID 应用。 有关详细信息,请参阅使用 Azure 门户注册应用。
登录 Azure 门户。
注意
要使用的门户根据 Microsoft Entra ID 应用程序是在 Azure 公有云中运行还是在国家云或主权云中运行而异。 有关详细信息,请参阅国家云。
如果有权访问多个租户、订阅或目录,请单击顶部菜单中的“目录 + 订阅”(带筛选器的目录)图标,以切换到要注册应用程序的目录。
搜索并选择 Microsoft Entra ID。
在“管理”中,选择“应用注册”>“新建注册”。
对于“名称”,请输入应用程序的名称。
在“支持的帐户类型”部分中,选择“仅组织目录中的帐户(单一租户)”。
在“重定向 URI (可选)”部分中,为“选择平台”选择“公共客户端/本机(移动和桌面)”,并输入重定向 URI。 在下面的示例中,重定向 URI 值为
http://localhost
。单击“注册”。
在应用程序页的“概述”页上的“概要”部分中,复制以下值:
- 应用程序(客户端) ID
- 目录(租户)ID
- 在“重定向 URI”中,为之前在此过程中输入的公共客户端重定向 URI。
向 AzureDatabricks 添加已注册应用程序的必需权限。 只有管理员用户可执行此步骤。 如果在执行此操作时遇到与权限相关的问题,请与管理员联系以寻求帮助。
在应用程序页的“概述”页上,在“开始使用”选项卡上单击“查看 API 权限”。
单击“添加权限”。
在“请求 API 权限”窗格中,单击“我的组织使用的 API”选项卡,搜索并选择“AzureDatabricks”。
启用“user_impersonation”复选框,然后单击“添加权限”。
单击“向 ### 授予管理员同意”,然后单击“是”。 若要执行此步骤,必须具有管理员用户身份或有权向应用程序授予同意。 如果未看到“为 ### 授予管理员同意”,或者跳过此操作,则必须在首次使用应用程序提供同意时使用授权代码流(交互式)。 之后便可使用用户名-密码流(编程式)方法。
可将其他用户添加到应用程序。 有关详细信息,请参阅向企业应用程序分配用户帐户中的 Azure 门户说明或向 Microsoft Entra ID(旧称 Azure Active Directory)中的应用程序分配用户和组中的 PowerShell 说明。 用户如果没有所需的权限,则无法获取令牌。
获取 Microsoft Entra ID 访问令牌
若要获取 Microsoft Entra ID 访问令牌,可以使用:
如果出现以下情况,必须使用授权代码流(交互式)来获取 Microsoft Entra ID 访问令牌:
- Microsoft Entra ID 中启用了双重身份验证。
- Microsoft Entra ID 中启用了联合身份验证。
- 在应用程序注册期间,不会向你授予对已注册的应用程序的同意。
如果你有权使用用户名和密码登录,则可使用用户名-密码流(编程式)获取 Microsoft Entra ID 访问令牌。
授权代码流(交互式)
可通过两个步骤使用授权代码流来获取 Microsoft Entra ID 访问令牌。
- 请求授权代码,该代码会启动一个浏览器窗口并请求 Azure 用户登录。 用户成功登录后,将返回授权代码。
- 使用授权代码获取 Microsoft Entra ID 访问令牌。 根据所使用的方法,还可以同时返回刷新令牌,该令牌可用于刷新 Microsoft Entra ID 访问令牌。
完成这两个步骤的一个方法是使用 Web 浏览器和 curl。 为此,请使用 Web 浏览器获取授权代码,然后使用该授权代码和 curl
获取 Microsoft Entra ID 令牌。 此方法不提供刷新令牌。
另一种方法是使用 MSAL Python 库。 为此,请运行单个脚本,该脚本使用 Web 浏览器获取授权代码,然后使用授权代码获取访问令牌令牌和刷新令牌。
这两种方法都假定你已登录到 Azure。 如果未登录,Web 浏览器会提示你登录。
使用 Web 浏览器和 curl 获取 Microsoft Entra ID 令牌
收集以下信息:
参数 说明 租户 ID 在 Azure 门户中配置应用程序的 Microsoft Entra ID 中注册的相关应用程序的目录(租户)ID。 客户端 ID 在 Microsoft Entra ID 中注册的相关应用程序的“应用程序(客户端) ID”。 重定向 URI 在 Azure AD 中注册的相关应用程序的相应重定向 URI(例如 http://localhost
)。 会向此 URI 发送身份验证响应(包含授权代码)。使用 Web 浏览器浏览到以下 URL,获取授权代码。 请相应地替换以下 URL 示例中的字段。 请注意,URL 必须作为单行发送;为了便于阅读,已将换行符添加到以下 URL。 有关详细信息,请参阅请求授权代码。
https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/authorize?client_id=<client-id> &response_type=code &redirect_uri=<redirect-uri> &response_mode=query &scope=2ff814a6-3304-4ab8-85cb-cd0e6f879c1d%2F.default &state=<state>
将:
<tenant-id>
替换为已注册应用程序的租户 ID。<client-id>
替换为已注册应用程序的客户端 ID。<redirect-uri>
替换为已注册应用程序的重定向 URI。 此 URI 必须采用 URL 编码(百分比编码)格式。 例如,http://localhost
为http%3A%2F%2Flocalhost
。<state>
替换为一个随机数或一些编码信息。 为了帮助检查信息交换的完整性,此状态值应与此过程稍后返回的 URL 中的值匹配。
不要更改
scope
参数的值。 它表示 Azure Databricks 的编程 ID(2ff814a6-3304-4ab8-85cb-cd0e6f879c1d
),以及默认作用域(/.default
,URL 编码为%2f.default
)。例如:
https://login.microsoftonline.com/a1bc2d34-5e67-8f89-01ab-c2345d6c78de/oauth2/v2.0/authorize?client_id=12a34b56-789c-0d12-e3fa-b456789c0123 &response_type=code &redirect_uri=http%3A%2F%2Flocalhost &response_mode=query &scope=2ff814a6-3304-4ab8-85cb-cd0e6f879c1d%2F.default &state=12345
将 URL 作为单行粘贴到 Web 浏览器中,并在出现提示时登录到 Azure。
授权代码位于返回 URL 的
code
字段中。 将授权代码保存在安全的位置。 此外,进行检查以确保state
字段的值与之前在此过程中提供的值匹配。完整的返回 URL 将如下所示(为简洁起见,此处将完整的
code
字段值缩短为0.ASkAIj...RxgFhSAA
):http://localhost/?code=0.ASkAIj...RxgFhSAA&state=12345&session_state=c44574d5-38ba-4f93-b2a3-a830db8e8cdf
使用授权代码以及
curl
来获取 Microsoft Entra ID 访问令牌。curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' \ https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token \ -d 'client_id=<client-id>' \ -d 'scope=2ff814a6-3304-4ab8-85cb-cd0e6f879c1d%2F.default' \ -d 'code=<authorization-code>' \ -d 'redirect_uri=<redirect-uri>' \ -d 'grant_type=authorization_code' \ -d 'state=<state>'
将:
<tenant-id>
替换为已注册应用程序的租户 ID。<client-id>
替换为已注册应用程序的客户端 ID。<authorization-code>
替换为授权代码。<redirect-uri>
替换为已注册应用程序的重定向 URI。 此 URI 必须采用 URL 编码(百分比编码)格式。 例如,http://localhost
为http%3A%2F%2Flocalhost
。<state>
替换为一个随机数或一些编码信息。 为了帮助检查信息交换的完整性,此状态值应与此过程稍后的响应有效负载中的值匹配。
不要更改
scope
参数的值。 它表示 Azure Databricks 的编程 ID(2ff814a6-3304-4ab8-85cb-cd0e6f879c1d
),以及默认作用域(/.default
,URL 编码为%2f.default
)。例如:
curl -X POST -H 'Content-Type: application/x-www-form-urlencoded' \ https://login.microsoftonline.com/a1bc2d34-5e67-8f89-01ab-c2345d6c78de/oauth2/v2.0/token \ -d 'client_id=12a34b56-789c-0d12-e3fa-b456789c0123' \ -d 'scope=2ff814a6-3304-4ab8-85cb-cd0e6f879c1d%2F.default' \ -d 'code=0.ASkAIj...RxgFhSAA' \ -d 'redirect_uri=http%3A%2F%2Flocalhost' \ -d 'grant_type=authorization_code' \ -d 'state=12345'
Microsoft Entra ID 令牌位于调用结果内的
access_token
值中。 请务必检查state
值是否与之前在此过程中提供的值匹配。
使用 MSAL Python 库获取 Microsoft Entra ID 令牌
收集以下信息:
参数 说明 租户 ID 在 Azure 门户中配置应用程序的 Microsoft Entra ID 中注册的相关应用程序的目录(租户)ID。 客户端 ID 在 Microsoft Entra ID 中注册的相关应用程序的“应用程序(客户端) ID”。 此过程假设你已将
http://localhost
设置为在 Microsoft Entra ID 中注册的相关应用程序的重定向 URI。通过运行
pip install msal
在本地计算机上安装 MSAL Python SDK。在本地计算机上将以下代码保存为
get-tokens.py
。# Given the client ID and tenant ID for an app registered in Azure, # provide a <ms-entra-id> access token and a refresh token. # If the caller is not already signed in to Azure, the caller's # web browser will prompt the caller to sign in first. # pip install msal from msal import PublicClientApplication import sys # You can hard-code the registered app's client ID and tenant ID here, # or you can provide them as command-line arguments to this script. client_id = '<client-id>' tenant_id = '<tenant-id>' # Do not modify this variable. It represents the programmatic ID for # Azure Databricks along with the default scope of '/.default'. scopes = [ '2ff814a6-3304-4ab8-85cb-cd0e6f879c1d/.default' ] # Check for too few or too many command-line arguments. if (len(sys.argv) > 1) and (len(sys.argv) != 3): print("Usage: get-tokens.py <client ID> <tenant ID>") exit(1) # If the registered app's client ID and tenant ID are provided as # command-line variables, set them here. if len(sys.argv) > 1: client_id = sys.argv[1] tenant_id = sys.argv[2] app = PublicClientApplication( client_id = client_id, authority = "https://login.microsoftonline.com/" + tenant_id ) acquire_tokens_result = app.acquire_token_interactive( scopes = scopes ) if 'error' in acquire_tokens_result: print("Error: " + acquire_tokens_result['error']) print("Description: " + acquire_tokens_result['error_description']) else: print("Access token:\n") print(acquire_tokens_result['access_token']) print("\nRefresh token:\n") print(acquire_tokens_result['refresh_token'])
执行下列操作之一:
- 在上面的代码中,将
<client-id>
替换为已注册应用程序的客户端 ID,将<tenant-id>
替换为已注册应用程序的租户 ID,然后运行脚本(例如python get-tokens.py
)。 - 在运行脚本(例如
python get-tokens.py 12a34b56-789c-0d12-e3fa-b456789c0123 a1bc2d34-5e67-8f89-01ab-c2345d6c78de
)时,提供已注册应用程序的客户端 ID 和已注册应用程序的租户 ID。
- 在上面的代码中,将
如果 Web 浏览器发出提示,请登录到 Azure。
Microsoft Entra ID 访问和刷新令牌会打印在输出中。
用户名-密码流(编程式)
如果你有权使用用户名和密码登录,请收集以下信息:
参数 说明 租户 ID 在 Azure 门户中配置应用程序的 Microsoft Entra ID 中注册的相关应用程序的目录(租户)ID。 客户端 ID 在 Microsoft Entra ID 中注册的相关应用程序的“应用程序(客户端) ID”。 用户名和密码 租户中用户的用户名(即登录到 Azure 门户时的电子邮件地址)和密码。 此过程假设你已将
http://localhost
设置为在 Microsoft Entra ID 中注册的相关应用程序的重定向 URI。通过运行
pip install msal
在本地计算机上安装 MSAL Python SDK。在本地计算机上将以下代码保存为
get-tokens-for-user.py
。# Given the client ID and tenant ID for an app registered in Azure, # along with an Azure username and password, # provide a <ms-entra-id> access token and a refresh token. # If the caller is not already signed in to Azure, the caller's # web browser will prompt the caller to sign in first. # pip install msal from msal import PublicClientApplication import sys # You can hard-code the registered app's client ID and tenant ID here, # along with the Azure username and password, # or you can provide them as command-line arguments to this script. client_id = '<client-id>' tenant_id = '<tenant-id>' username = '<username>' password = '<password>' # Do not modify this variable. It represents the programmatic ID for # Azure Databricks along with the default scope of '/.default'. scope = [ '2ff814a6-3304-4ab8-85cb-cd0e6f879c1d/.default' ] # Check for too few or too many command-line arguments. if (len(sys.argv) > 1) and (len(sys.argv) != 5): print("Usage: get-tokens-for-user.py <client ID> <tenant ID> <username> <password>") exit(1) # If the registered app's client ID and tenant ID along with the # Azure username and password are provided as command-line variables, # set them here. if len(sys.argv) > 1: client_id = sys.argv[1] tenant_id = sys.argv[2] username = sys.argv[3] password = sys.argv[4] app = PublicClientApplication( client_id = client_id, authority = "https://login.microsoftonline.com/" + tenant_id ) acquire_tokens_result = app.acquire_token_by_username_password( username = username, password = password, scopes = scope ) if 'error' in acquire_tokens_result: print("Error: " + acquire_tokens_result['error']) print("Description: " + acquire_tokens_result['error_description']) else: print("Access token:\n") print(acquire_tokens_result['access_token']) print("\nRefresh token:\n") print(acquire_tokens_result['refresh_token'])
执行下列操作之一:
- 在上面的代码中,将
<client-id>
替换为已注册应用程序的客户端 ID,将<tenant-id>
替换为已注册应用程序的租户 ID,将<username>
替换为用户名,并将<password>
替换为密码,然后运行脚本(例如python get-tokens-for-user.py
)。 - 在运行脚本(例如
python get-tokens-for-user.py 12a34b56-789c-0d12-e3fa-b456789c0123 a1bc2d34-5e67-8f89-01ab-c2345d6c78de someone@example.com "MyPa55w&rd!"
)时,提供已注册应用程序的客户端 ID、已注册应用程序的租户 ID、用户名和密码。 如果命令行参数包含特殊字符,则应为其加上引号。
- 在上面的代码中,将
Microsoft Entra ID 访问和刷新令牌将打印到终端。
使用 Microsoft Entra ID 访问令牌访问 Databricks REST API
本部分介绍如何使用 Microsoft Entra ID 访问令牌调用 Databricks REST API。 在以下示例中,请将 <access-token>
替换为 Microsoft Entra ID 访问令牌,并将 <databricks-instance>
替换为 Azure Databricks 部署的每工作区 URL。
Python 示例
此示例演示如何列出 Azure Databricks 工作区中的群集。
import requests
import json
databricks_instance = '<databricks-instance>'
api_version = '/api/2.0'
api_command = '/clusters/list'
url = f"https://{databricks_instance}{api_version}{api_command}"
access_token = '<access-token>'
response = requests.get(
url = url,
headers = { 'Authorization': "Bearer " + access_token}
)
print(json.dumps(json.loads(response.text), indent = 2))
注意
如果你不是管理员用户,但想以管理员用户身份登录,则除了 'Authorization' : 'Bearer '
标头外,还必须提供 标头,并且对于 Azure 中的工作区资源,你必须是参与者或所有者角色。 按如下所示构造 X-Databricks-Azure-Workspace-Resource-Id
值:
# ...
subscription = '<azure-subscription-id>'
resource_group = '<azure-resource-group-name>'
workspace = '<databricks-workspace-name-in-azure>'
db_resource_id = '/subscriptions/%s/resourcegroups/%s/providers/microsoft.databricks/workspaces/%s' % (
subscription,
resource_group,
workspace
)
# ...
headers = {
'Authorization': "Bearer " + access_token,
'X-Databricks-Azure-Workspace-Resource-Id': db_resource_id
}
# ...
若要在 Azure 中获取订阅、资源和工作区信息,请参阅 打开资源。 要打开目标资源,可以在 Azure 中搜索 Azure Databricks 服务类型以及你了解的有关目标 Azure Databricks 工作区的任何其他信息。
curl
实例
curl -X GET \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access-token>' \
https://<databricks-instance>/api/2.0/clusters/list
刷新 Microsoft Entra ID 访问令牌
如果你获取了刷新令牌和 Microsoft Entra ID 访问令牌,可使用刷新令牌来获取新的令牌。 默认情况下,Microsoft Entra ID 访问令牌的生存期为 60 到 90 分钟之间的随机时长(平均 75 分钟)。 可使用 Microsoft Entra ID(前 Azure Active Directory)中可配置的令牌生存期中的方法配置 Microsoft Entra ID 访问令牌的生存期。
下面的示例演示如何使用 MSAL Python 库以及刷新令牌来获取新令牌。
在本地计算机上将以下代码保存为
refresh-tokens.py
。# Given the client ID and tenant ID for an app registered in Azure, # along with a refresh token, provide a new <ms-entra-id> access token and # refresh token. # If the caller is not already signed in to Azure, the caller's # web browser will prompt the caller to sign in first. # pip install msal from msal import PublicClientApplication import sys # You can hard-code the registered app's client ID, tenant ID, # and refresh token here, or you can provide them as command-line # arguments to this script. client_id = '<client-id>' tenant_id = '<refresh-token' refresh_token = '<refresh-token>' # Do not modify this variable. It represents the programmatic ID for # Azure Databricks along with the default scope of '.default'. scope = [ '2ff814a6-3304-4ab8-85cb-cd0e6f879c1d/.default' ] # Check for too few or too many command-line arguments. if (len(sys.argv) > 1) and (len(sys.argv) != 4): print("Usage: refresh-tokens.py <client ID> <tenant ID> <refresh token>") exit(1) # If the registered app's client ID, tenant ID, and refresh token are # provided as command-line variables, set them here. if len(sys.argv) > 1: client_id = sys.argv[1] tenant_id = sys.argv[2] refresh_token = sys.argv[3] app = PublicClientApplication( client_id = client_id, authority = "https://login.microsoftonline.com/" + tenant_id ) acquire_tokens_result = app.acquire_token_by_refresh_token( refresh_token = refresh_token, scopes = scope ) if 'error' in acquire_tokens_result: print("Error: " + acquire_tokens_result['error']) print("Description: " + acquire_tokens_result['error_description']) else: print("\nNew access token:\n") print(acquire_tokens_result['access_token']) print("\nNew refresh token:\n") print(acquire_tokens_result['refresh_token'])
执行下列操作之一:
- 在上面的代码中,将
<client-id>
替换为已注册应用程序的客户端 ID,将<tenant-id>
替换为已注册应用程序的租户 ID,并将<refresh-token>
替换为刷新令牌,然后运行脚本(例如python get-tokens-for-user.py
)。 - 在运行脚本(例如
python refresh-tokens.py 12a34b56-789c-0d12-e3fa-b456789c0123 a1bc2d34-5e67-8f89-01ab-c2345d6c78de "0.ASkAIj...huE84ALg"
)时,提供已注册应用程序的客户端 ID、已注册应用程序的租户 ID 和刷新令牌。 如果命令行参数包含特殊字符,则应为其加上引号。
- 在上面的代码中,将
新的 Microsoft Entra ID 访问和刷新令牌将打印到终端。