为 Azure 机器学习资源和工作流设置身份验证Set up authentication for Azure Machine Learning resources and workflows

适用于:是基本版是企业版               (升级到企业版APPLIES TO: yesBasic edition yesEnterprise edition                    (Upgrade to Enterprise edition)

了解如何向 Azure 机器学习工作区进行身份验证,以及如何向部署为 Web 服务的模型进行身份验证。Learn how to authenticate to your Azure Machine Learning workspace, and to models deployed as web services.

通常,可将两种类型的身份验证用于 Azure 机器学习:In general, there are two types of authentication that you can use with Azure Machine Learning:

  • 交互式:你可以使用 Azure Active Directory 中的帐户直接进行身份验证,或者使用它来获取用于身份验证的令牌。Interactive: You use your account in Azure Active Directory to either directly authenticate, or to get a token that is used for authentication. 在试验和迭代开发期间,你使用交互式身份验证。Interactive authentication is used during experimentation and iterative development. 或者,如果你想基于每个用户控制对资源(例如 Web 服务)的访问,也使用此类身份验证。Or where you want to control access to resources (such as a web service) on a per-user basis.
  • 服务主体:在 Azure Active Directory 中创建一个服务主体帐户,并使用它来进行身份验证或获取令牌。Service principal: You create a service principal account in Azure Active Directory, and use it to authenticate or get a token. 当需要使用自动化过程向服务进行身份验证时,将使用服务主体,无需用户交互。A service principal is used when you need an automated process to authenticate to the service without requiring user interaction. 例如连续集成和部署脚本,它可以在训练代码每次发生更改时对模型进行训练和测试。For example, a continuous integration and deployment script that trains and tests a model every time the training code changes. 在下列情况下,还可以使用服务主体来检索一个用于向 Web 服务进行身份验证的令牌:你不想要求服务的最终用户进行身份验证;You might also use a service principal to retrieve a token to authenticate to a web service, if you don't want to require the end user of the service to authenticate. 或者,没有直接使用 Azure Active Directory 执行最终用户身份验证。Or where the end-user authentication isn't performed directly using Azure Active Directory.

无论使用何种身份验证类型,都可以使用基于角色的访问控制 (RBAC) 来限定允许拥有的对资源的访问权限级别。Regardless of the authentication type used, role-based access control (RBAC) is used to scope the level of access allowed to the resources. 例如,用于获取已部署模型的访问令牌的帐户只需要对工作区的读取访问权限。For example, an account that is used to get the access token for a deployed model only needs read access to the workspace. 有关 RBAC 的详细信息,请参阅管理对 Azure 机器学习工作区的访问权限For more information on RBAC, see Manage access to Azure Machine Learning workspace.

先决条件Prerequisites

交互式身份验证Interactive authentication

文档和样本中的大多数示例都使用交互式身份验证。Most examples in the documentation and samples use interactive authentication. 例如,当使用 SDK 时,有两个函数调用会自动提示你使用基于 UI 的身份验证流:For example, when using the SDK there are two function calls that will automatically prompt you with a UI-based authentication flow:

  • 调用 from_config() 函数会触发提示。Calling the from_config() function will issue the prompt.

    from azureml.core import Workspace
    ws = Workspace.from_config()
    

    函数 from_config() 查找包含工作区连接信息的 JSON 文件。The from_config() function looks for a JSON file containing your workspace connection information.

  • 使用 Workspace 构造函数来提供订阅、资源组和工作区信息时,系统也会提示你进行交互式身份验证。Using the Workspace constructor to provide subscription, resource group, and workspace information, will also prompt for interactive authentication.

    ws = Workspace(subscription_id="your-sub-id",
                  resource_group="your-resource-group-id",
                  workspace_name="your-workspace-name"
                  )
    

提示

如果你可访问多个租户,则可能需要导入类并显式定义目标租户。If you have access to multiple tenants, you may need to import the class and explicitly define what tenant you are targeting. 与上述调用类似,为 InteractiveLoginAuthentication 调用构造函数也会提示你登录。Calling the constructor for InteractiveLoginAuthentication will also prompt you to login similar to the calls above.

from azureml.core.authentication import InteractiveLoginAuthentication
interactive_auth = InteractiveLoginAuthentication(tenant_id="your-tenant-id")

服务主体身份验证Service principal authentication

若要使用服务主体 (SP) 身份验证,必须先创建 SP,并向其授予对工作区的访问权限。To use service principal (SP) authentication, you must first create the SP and grant it access to your workspace. 如前文所述,将使用 Azure 基于角色的访问控制 (RBAC) 来控制访问,因此你还必须确定要授予 SP 的访问权限。As mentioned earlier, Azure role-based access control (RBAC) is used to control access, so you must also decide what access to grant the SP.

重要

使用服务主体时,请向它授予它所用于的__任务所需的最低访问权限__。When using a service principal, grant it the minimum access required for the task it is used for. 例如,如果服务主体仅用于读取 Web 部署的访问令牌,则不要向服务主体授予所有者或参与者访问权限。For example, you would not grant a service principal owner or contributor access if all it is used for is reading the access token for a web deployment.

授予最低访问权限的原因是服务主体使用密码进行身份验证,并且该密码可以存储为自动化脚本的一部分。The reason for granting the least access is that a service principal uses a password to authenticate, and the password may be stored as part of an automation script. 如果密码泄漏,由于用户仅拥有执行特定任务所需的最低访问权限,因此可最大程度地减少对 SP 的恶意使用。If the password is leaked, having the minimum access required for a specific tasks minimizes the malicious use of the SP.

创建 SP 并向其授予对工作区的访问权限的最简单方法是使用 Azure CLIThe easiest way to create an SP and grant access to your workspace is by using the Azure CLI. 若要创建服务主体并向其授予对工作区的访问权限,请执行以下步骤:To create a service principal and grant it access to your workspace, use the following steps:

备注

你必须是订阅的管理员才能执行所有这些步骤。You must be an admin on the subscription to perform all of these steps.

  1. 对 Azure 订阅进行身份验证:Authenticate to your Azure subscription:

    az login
    

    如果 CLI 可以打开默认的浏览器,则它会打开该浏览器并加载登录页。If the CLI can open your default browser, it will do so and load a sign-in page. 否则,需要打开浏览器并按照命令行中的说明操作。Otherwise, you need to open a browser and follow the instructions on the command line. 按说明操作时,需要浏览到 https://aka.ms/devicelogin 并输入授权代码。The instructions involve browsing to https://aka.ms/devicelogin and entering an authorization code.

    提示

    登录后,你将看到与你的 Azure 帐户关联的订阅列表。After logging in, you see a list of subscriptions associated with your Azure account. isDefault: true 的订阅信息是当前已激活的 Azure CLI 命令订阅。The subscription information with isDefault: true is the currently activated subscription for Azure CLI commands. 此订阅必须与包含 Azure 机器学习工作区的订阅相同。This subscription must be the same one that contains your Azure Machine Learning workspace. 通过访问工作区的概述页,可以从 Azure 门户中找到订阅 ID。You can find the subscription ID from the Azure portal by visiting the overview page for your workspace. 还可以使用 SDK 从工作区对象获取订阅 ID。You can also use the SDK to get the subscription ID from the workspace object. 例如,Workspace.from_config().subscription_idFor example, Workspace.from_config().subscription_id.

    若要选择另一个订阅,请使用 az account set -s <subscription name or ID> 命令,并指定要切换到的订阅名称或 ID。To select another subscription, use the az account set -s <subscription name or ID> command and specify the subscription name or ID to switch to. 有关订阅选择的详细信息,请参阅使用多个 Azure 订阅For more information about subscription selection, see Use multiple Azure Subscriptions.

    有关其他身份验证方法,请参阅使用 Azure CLI 登录For other methods of authenticating, see Sign in with Azure CLI.

  2. 安装 Azure 机器学习扩展:Install the Azure Machine Learning extension:

    az extension add -n azure-cli-ml
    
  3. 创建服务主体。Create the service principal. 在以下示例中,将创建一个名为 ml-auth 的 SP:In the following example, an SP named ml-auth is created:

    az ad sp create-for-rbac --sdk-auth --name ml-auth
    

    输出将是类似于如以下所示的 JSON。The output will be a JSON similar to the following. 记下 clientIdclientSecrettenantId 字段,因为在本文的其他步骤中你需要用到它们。Take note of the clientId, clientSecret, and tenantId fields, as you will need them for other steps in this article.

    {
        "clientId": "your-client-id",
        "clientSecret": "your-client-secret",
        "subscriptionId": "your-sub-id",
        "tenantId": "your-tenant-id",
        "activeDirectoryEndpointUrl": "https://login.microsoftonline.com",
        "resourceManagerEndpointUrl": "https://management.azure.com",
        "activeDirectoryGraphResourceId": "https://graph.chinacloudapi.cn",
        "sqlManagementEndpointUrl": "https://management.core.chinacloudapi.cn:5555",
        "galleryEndpointUrl": "https://gallery.azure.com/",
        "managementEndpointUrl": "https://management.core.chinacloudapi.cn"
    }
    
  4. 使用上一步返回的 clientId 值检索服务主体的详细信息:Retrieve the details for the service principal by using the clientId value returned in the previous step:

    az ad sp show --id your-client-id
    

    下面的 JSON 是命令的输出的简化示例。The following JSON is a simplified example of the output from the command. 记下 objectId 字段,因为你将在接下来的步骤中用到它的值。Take note of the objectId field, as you will need its value for the next step.

    {
        "accountEnabled": "True",
        "addIns": [],
        "appDisplayName": "ml-auth",
        ...
        ...
        ...
        "objectId": "your-sp-object-id",
        "objectType": "ServicePrincipal"
    }
    
  5. 允许 SP 访问你的 Azure 机器学习工作区。Allow the SP to access your Azure Machine Learning workspace. 你将需要工作区名称,以及分别针对 -w-g 参数的资源组名称。You will need your workspace name, and its resource group name for the -w and -g parameters, respectively. 对于 --user 参数,请使用 objectId 之前步骤中的 值。For the --user parameter, use the objectId value from the previous step. --role 参数用于为服务主体设置访问角色。The --role parameter allows you to set the access role for the service principal. 在以下示例中,将向 SP 分配所有者角色。In the following example, the SP is assigned to the owner role.

    重要

    所有者访问权限允许服务主体在工作区中执行几乎所有操作。Owner access allows the service principal to do virtually any operation in your workspace. 本文档中使用它来演示如何授予访问权限;在生产环境中,Microsoft 建议你仅向服务主体授予行使目标角色职能所需的最低访问权限。It is used in this document to demonstrate how to grant access; in a production environment Microsoft recommends granting the service principal the minimum access needed to perform the role you intend it for. 有关详细信息,请参阅管理对 Azure 机器学习工作区的访问权限For more information, see Manage access to Azure Machine Learning workspace.

    az ml workspace share -w your-workspace-name -g your-resource-group-name --user your-sp-object-id --role owner
    

    此调用在成功时不会生成任何输出。This call does not produce any output on success.

从 SDK 中使用服务主体Use a service principal from the SDK

若要从 SDK 中使用服务主体向工作区进行身份验证,请使用 ServicePrincipalAuthentication 类构造函数。To authenticate to your workspace from the SDK, using the service principal, use the ServicePrincipalAuthentication class constructor. 使用创建服务提供程序时获得的值作为参数。Use the values you got when creating the service provider as the parameters. tenant_id 参数映射到上述的 tenantIdservice_principal_id 映射到 clientIdservice_principal_password 映射到 clientSecretThe tenant_id parameter maps to tenantId from above, service_principal_id maps to clientId, and service_principal_password maps to clientSecret.

from azureml.core.authentication import ServicePrincipalAuthentication

sp = ServicePrincipalAuthentication(tenant_id="your-tenant-id", # tenantID
                                    service_principal_id="your-client-id", # clientId
                                    service_principal_password="your-client-secret") # clientSecret

sp 变量现在包含身份验证对象,可直接在 SDK 中使用。The sp variable now holds an authentication object that you use directly in the SDK. 通常,建议将上述 ID/机密存储在环境变量中,如下面的代码所示。In general, it is a good idea to store the ids/secrets used above in environment variables as shown in the following code. 存储在环境变量中可防止将信息意外地签入到 GitHub 存储库中。Storing in environment variables prevents the information from being accidentally checked into a GitHub repo.

import os

sp = ServicePrincipalAuthentication(tenant_id=os.environ['AML_TENANT_ID'],
                                    service_principal_id=os.environ['AML_PRINCIPAL_ID'],
                                    service_principal_password=os.environ['AML_PRINCIPAL_PASS'])

对于在 Python 中运行并主要使用 SDK 的自动化工作流,在大多数情况下,都可按原样使用此对象进行身份验证。For automated workflows that run in Python and use the SDK primarily, you can use this object as-is in most cases for your authentication. 以下代码使用你创建的身份验证对象向你的工作区进行身份验证。The following code authenticates to your workspace using the auth object you created.

from azureml.core import Workspace

ws = Workspace.get(name="ml-example",
                   auth=sp,
                   subscription_id="your-sub-id")
ws.get_details()

从 Azure CLI 中使用服务主体Use a service principal from the Azure CLI

可以将服务主体用于 Azure CLI 命令。You can use a service principal for Azure CLI commands. 有关详细信息,请参阅使用服务主体登录For more information, see Sign in using a service principal.

将服务主体用于 REST API(预览版)Use a service principal with the REST API (preview)

还可以使用服务主体向 Azure 机器学习 REST API(预览版)进行身份验证。The service principal can also be used to authenticate to the Azure Machine Learning REST API (preview). 如果使用 Azure Active Directory 客户端凭据授予流,则可在自动化工作流中进行无外设身份验证的服务到服务调用。You use the Azure Active Directory client credentials grant flow, which allow service-to-service calls for headless authentication in automated workflows. 这些示例使用 Python 和 Node.js 中的 ADAL 库实现,但也可以使用支持 OpenID Connect 1.0 的任何开放源代码库。The examples are implemented with the ADAL library in both Python and Node.js, but you can also use any open-source library that supports OpenID Connect 1.0.

备注

MSAL.js 库比 ADAL 更新,但不能使用 MSAL.js 的客户端凭据进行服务到服务的身份验证,因为它主要是一个客户端库,适用于与特定用户关联的交互式/UI 身份验证。MSAL.js is a newer library than ADAL, but you cannot do service-to-service authentication using client credentials with MSAL.js, since it is primarily a client-side library intended for interactive/UI authentication tied to a specific user. 我们建议使用如下所示的 ADAL,通过 REST API 生成自动化工作流。We recommend using ADAL as shown below to build automated workflows with the REST API.

Node.jsNode.js

使用以下步骤,通过 Node.js 生成身份验证令牌。Use the following steps to generate an auth token using Node.js. 在你的环境中运行 npm install adal-nodeIn your environment, run npm install adal-node. 然后,使用在上述步骤中创建的服务主体中的 tenantIdclientIdclientSecret,作为以下脚本中匹配变量的值。Then, use your tenantId, clientId, and clientSecret from the service principal you created in the steps above as values for the matching variables in the following script.

const adal = require('adal-node').AuthenticationContext;

const authorityHostUrl = 'https://login.microsoftonline.com/';
const tenantId = 'your-tenant-id';
const authorityUrl = authorityHostUrl + tenantId;
const clientId = 'your-client-id';
const clientSecret = 'your-client-secret';
const resource = 'https://management.azure.com/';

const context = new adal(authorityUrl);

context.acquireTokenWithClientCredentials(
  resource,
  clientId,
  clientSecret,
  (err, tokenResponse) => {
    if (err) {
      console.log(`Token generation failed due to ${err}`);
    } else {
      console.dir(tokenResponse, { depth: null, colors: true });
    }
  }
);

变量 tokenResponse 是包含令牌和关联元数据(如过期时间)的对象。The variable tokenResponse is an object that includes the token and associated metadata such as expiration time. 令牌的有效时间为 1 个小时,可以通过再次运行相同的调用检索一个新令牌来对令牌进行刷新。Tokens are valid for 1 hour, and can be refreshed by running the same call again to retrieve a new token. 下面的代码片段是示例响应。The following snippet is a sample response.

{
    tokenType: 'Bearer',
    expiresIn: 3599,
    expiresOn: 2019-12-17T19:15:56.326Z,
    resource: 'https://management.azure.com/',
    accessToken: "random-oauth-token",
    isMRRT: true,
    _clientId: 'your-client-id',
    _authority: 'https://login.microsoftonline.com/your-tenant-id'
}

使用 accessToken 属性获取身份验证令牌。Use the accessToken property to fetch the auth token. 请参阅 REST API 文档,获取如何使用令牌进行 API 调用的示例。See the REST API documentation for examples on how to use the token to make API calls.

PythonPython

使用以下步骤,通过 Python 生成身份验证令牌。Use the following steps to generate an auth token using Python. 在你的环境中运行 pip install adalIn your environment, run pip install adal. 然后,使用在上述步骤中创建的服务主体中的 tenantIdclientIdclientSecret,作为以下脚本中适合的变量的值。Then, use your tenantId, clientId, and clientSecret from the service principal you created in the steps above as values for the appropriate variables in the following script.

from adal import AuthenticationContext

client_id = "your-client-id"
client_secret = "your-client-secret"
resource_url = "https://login.microsoftonline.com"
tenant_id = "your-tenant-id"
authority = "{}/{}".format(resource_url, tenant_id)

auth_context = AuthenticationContext(authority)
token_response = auth_context.acquire_token_with_client_credentials("https://management.azure.com/", client_id, client_secret)
print(token_response)

变量 token_response 是包含令牌和关联元数据(如过期时间)的字典。The variable token_response is a dictionary that includes the token and associated metadata such as expiration time. 令牌的有效时间为 1 个小时,可以通过再次运行相同的调用检索一个新令牌来对令牌进行刷新。Tokens are valid for 1 hour, and can be refreshed by running the same call again to retrieve a new token. 下面的代码片段是示例响应。The following snippet is a sample response.

{
    'tokenType': 'Bearer',
    'expiresIn': 3599,
    'expiresOn': '2019-12-17 19:47:15.150205',
    'resource': 'https://management.azure.com/',
    'accessToken': 'random-oauth-token',
    'isMRRT': True,
    '_clientId': 'your-client-id',
    '_authority': 'https://login.microsoftonline.com/your-tenant-id'
}

使用 token_response["accessToken"] 获取身份验证令牌。Use token_response["accessToken"] to fetch the auth token. 请参阅 REST API 文档,获取如何使用令牌进行 API 调用的示例。See the REST API documentation for examples on how to use the token to make API calls.

Web 服务身份验证Web-service authentication

Azure 机器学习创建的模型部署提供了两种身份验证方法:The model deployments created by Azure Machine Learning provide two authentication methods:

  • 基于密钥:使用静态密钥向 Web 服务进行身份验证。key-based: A static key is used to authenticate to the web service.

  • 基于令牌:必须从工作区获取一个临时令牌,并使用该令牌向 Web 服务进行身份验证。token-based: A temporary token must be obtained from the workspace and used to authenticate to the web service. 此令牌在一段时间后将过期,并且必须刷新才能继续使用 Web 服务。This token expires after a period of time, and must be refreshed to continue working with the web service.

    备注

    只有部署到 Azure Kubernetes 服务时,基于令牌的身份验证才适用。Token-based authentication is only available when deploying to Azure Kubernetes Service.

基于密钥的 Web 服务身份验证Key-based web service authentication

部署在 Azure Kubernetes 服务 (AKS) 上的 Web 服务默认情况下会启用基于密钥的身份验证。Web-services deployed on Azure Kubernetes Service (AKS) have key-based auth enabled by default. 默认情况下,Azure 容器实例 (ACI) 部署的服务禁用基于密钥的身份验证,但你可以在创建 ACI Web 服务时通过设置 auth_enabled=True 来启用它。Azure Container Instances (ACI) deployed services have key-based auth disabled by default, but you can enable it by setting auth_enabled=Truewhen creating the ACI web-service. 以下代码是一个示例,演示了如何创建启用了基于密钥的身份验证的 ACI 部署配置。The following code is an example of creating an ACI deployment configuration with key-based auth enabled.

from azureml.core.webservice import AciWebservice

aci_config = AciWebservice.deploy_configuration(cpu_cores = 1,
                                                memory_gb = 1,
                                                auth_enabled=True)

然后可以通过 Model 类在部署中使用自定义 ACI 配置。Then you can use the custom ACI configuration in deployment using the Model class.

from azureml.core.model import Model, InferenceConfig


inference_config = InferenceConfig(entry_script="score.py",
                                   environment=myenv)
aci_service = Model.deploy(workspace=ws,
                       name="aci_service_sample",
                       models=[model],
                       inference_config=inference_config,
                       deployment_config=aci_config)
aci_service.wait_for_deployment(True)

若要提取身份验证密钥,请使用 aci_service.get_keys()To fetch the auth keys, use aci_service.get_keys(). 若要重新生成密钥,请使用 regen_key() 函数并传递“主要”或“辅助”密钥 。To regenerate a key, use the regen_key() function and pass either Primary or Secondary.

aci_service.regen_key("Primary")
# or
aci_service.regen_key("Secondary")

若要详细了解如何向已部署的模型进行身份验证,请参阅为部署为 Web 服务的模型创建客户端For more information on authenticating to a deployed model, see Create a client for a model deployed as a web service.

基于令牌的 Web 服务身份验证Token-based web-service authentication

如果要为 Web 服务启用令牌身份验证,用户必须向 Web 服务提供 Azure 机器学习 JSON Web 令牌才能访问。When you enable token authentication for a web service, users must present an Azure Machine Learning JSON Web Token to the web service to access it. 令牌在指定的时间范围后过期,需要刷新才能继续调用。The token expires after a specified time-frame and needs to be refreshed to continue making calls.

  • 部署到 Azure Kubernetes 服务时,会默认禁用令牌身份验证。Token authentication is disabled by default when you deploy to Azure Kubernetes Service.
  • 部署到 Azure 容器实例时,不支持令牌身份验证。Token authentication isn't supported when you deploy to Azure Container Instances.
  • 令牌身份验证不能与基于密钥的身份验证同时使用Token authentication can't be used at the same time as key-based authentication.

若要控制令牌身份验证,请在创建或更新部署时使用 token_auth_enabled 参数:To control token authentication, use the token_auth_enabled parameter when you create or update a deployment:

from azureml.core.webservice import AksWebservice
from azureml.core.model import Model, InferenceConfig

# Create the config
aks_config = AksWebservice.deploy_configuration()

#  Enable token auth and disable (key) auth on the webservice
aks_config = AksWebservice.deploy_configuration(token_auth_enabled=True, auth_enabled=False)

aks_service_name ='aks-service-1'

# deploy the model
aks_service = Model.deploy(workspace=ws,
                           name=aks_service_name,
                           models=[model],
                           inference_config=inference_config,
                           deployment_config=aks_config,
                           deployment_target=aks_target)

aks_service.wait_for_deployment(show_output = True)

如果启用了令牌身份验证,可以使用 get_token 方法检索 JSON Web (JWT) 令牌以及该令牌的到期时间:If token authentication is enabled, you can use the get_token method to retrieve a JSON Web Token (JWT) and that token's expiration time:

提示

如果使用服务主体获取令牌,并希望它具有检索令牌所需的最小访问权限,请向其分配工作区的“读取者”角色。If you use a service principal to get the token, and want it to have the minimum required access to retrieve a token, assign it to the reader role for the workspace.

token, refresh_by = aks_service.get_token()
print(token)

重要

需要在令牌的 refresh_by 时间后请求一个新令牌。You'll need to request a new token after the token's refresh_by time. 如果需要刷新 Python SDK 外的令牌,一个选择是使用服务主体身份验证的 REST API 定期进行 service.get_token() 调用,如前文所述。If you need to refresh tokens outside of the Python SDK, one option is to use the REST API with service-principal authentication to periodically make the service.get_token() call, as discussed previously.

我们强烈建议在 Azure Kubernetes 服务群集所在的相同区域中创建 Azure 机器学习工作区。We strongly recommend that you create your Azure Machine Learning workspace in the same region as your Azure Kubernetes Service cluster.

若要使用令牌进行身份验证,Web 服务将调用创建 Azure 机器学习工作区的区域。To authenticate with a token, the web service will make a call to the region in which your Azure Machine Learning workspace is created. 如果工作区的区域不可用,即使你的群集和工作区不在同一区域,你也无法获取 Web 服务的令牌。If your workspace's region is unavailable, you won't be able to fetch a token for your web service, even if your cluster is in a different region from your workspace. 结果是直到工作区的区域再次可用时,Azure AD 身份验证才可用。The result is that Azure AD Authentication is unavailable until your workspace's region is available again.

此外,群集区域和工作区区域的距离越远,获取令牌所需的时间就越长。Also, the greater the distance between your cluster's region and your workspace's region, the longer it will take to fetch a token.

后续步骤Next steps