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

了解如何对 Azure 机器学习工作区设置身份验证。Learn how to set up authentication to your Azure Machine Learning workspace. 在大多数情况下,Azure 机器学习工作区的身份验证基于 Azure Active Directory (Azure AD)。Authentication to your Azure Machine Learning workspace is based on Azure Active Directory (Azure AD) for most things. 通常,在连接到工作区时可使用 3 种身份验证工作流:In general, there three authentication workflows that you can use when connecting to the workspace:

  • 交互式:你可以使用 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 服务)的访问。Interactive authentication enables you 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.

  • 托管标识:在 Azure 虚拟机上使用 Azure 机器学习 SDK 时,可使用 Azure 的托管标识。Managed identity: When using the Azure Machine Learning SDK on an Azure Virtual Machine, you can use a managed identity for Azure. 此工作流允许 VM 使用托管标识连接到工作区,无需在 Python 代码中存储凭据或提示用户进行身份验证。This workflow allows the VM to connect to the workspace using the managed identity, without storing credentials in Python code or prompting the user to authenticate. 训练模型时,还可配置 Azure 机器学习计算群集来使用托管标识访问工作区。Azure Machine Learning compute clusters can also be configured to use a managed identity to access the workspace when training models.

重要

无论使用何种身份验证工作流,都可使用 Azure 基于角色的访问控制 (Azure RBAC) 来限定允许拥有的资源访问权限(授权)级别。Regardless of the authentication workflow used, Azure role-based access control (Azure RBAC) is used to scope the level of access (authorization) allowed to the resources. 例如,管理员或自动化过程可能具有创建计算实例的权限,但不使用它,而数据科学家可能会使用它,但不能删除或创建它。For example, an admin or automation process might have access to create a compute instance, but not use it, while a data scientist could use it, but not delete or create it. 有关详细信息,请参阅管理对 Azure 机器学习工作区的访问权限For more information, see Manage access to Azure Machine Learning workspace.

先决条件Prerequisites

Azure Active DirectoryAzure Active Directory

工作区的所有身份验证工作流都依赖于 Azure Active Directory。All the authentication workflows for your workspace rely on Azure Active Directory. 如果希望用户使用个人帐户进行身份验证,这些用户必须在 Azure AD 中有帐户。If you want users to authenticate using individual accounts, they must have accounts in your Azure AD. 如果希望使用服务主体,这些主体必须位于 Azure AD 中。If you want to use service principals, they must exist in your Azure AD. 托管标识也是 Azure AD 的一项功能。Managed identities are also a feature of Azure AD.

有关 Azure AD 的详细信息,请参阅什么是 Azure Active Directory 身份验证For more on Azure AD, see What is Azure Active Directory authentication.

创建 Azure AD 帐户后,请参阅管理对 Azure 机器学习工作区的访问权限,了解如何在 Azure 机器学习中授予帐户对工作区和其他操作的访问权限。Once you've created the Azure AD accounts, see Manage access to Azure Machine Learning workspace for information on granting them access to the workspace and other operations in Azure Machine Learning.

配置服务主体Configure a service principal

若要使用服务主体 (SP),必须先创建 SP,并向其授予对工作区的访问权限。To use a service principal (SP), you must first create the SP and grant it access to your workspace. 如前文所述,将使用 Azure 基于角色的访问控制 (Azure RBAC) 来控制访问,因此你还必须确定要授予 SP 的访问权限。As mentioned earlier, Azure role-based access control (Azure 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 订阅,可使用 az account set -s <subscription name or ID> 命令设置订阅。If you have multiple Azure subscriptions, you can use the az account set -s <subscription name or ID> command to set the subscription. 有关详细信息,请参阅使用多个 Azure 订阅For more information, 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.windows.net",
        "sqlManagementEndpointUrl": "https://management.core.windows.net:5555",
        "galleryEndpointUrl": "https://gallery.azure.com/",
        "managementEndpointUrl": "https://management.core.windows.net"
    }
    
  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 information on creating a custom role with the access needed for your scenario, 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.

配置托管标识Configure a managed identity

重要

仅当从 Azure 虚拟机或通过 Azure 机器学习计算群集使用 Azure 机器学习 SDK 时,托管标识才受支持。Managed identity is only supported when using the Azure Machine Learning SDK from an Azure Virtual Machine or with an Azure Machine Learning compute cluster. 可将托管标识与计算群集结合使用,该功能目前处于预览阶段。Using a managed identity with a compute cluster is currently in preview.

VM 的托管标识Managed identity with a VM

  1. 对 VM 上的 Azure 资源启用系统分配的托管标识Enable a system-assigned managed identity for Azure resources on the VM.

  2. Azure 门户选择你的工作区,然后依次选择“访问控制(IAM)”和“添加角色分配”,并从“将访问权限分配至”下拉列表中选择“虚拟机” 。From the Azure portal, select your workspace and then select Access Control (IAM), Add Role Assignment, and select Virtual Machine from the Assign Access To dropdown. 最后,选择 VM 的标识。Finally, select your VM's identity.

  3. 选择要分配给此标识的角色。Select the role to assign to this identity. 例如,参与者或自定义角色。For example, contributor or a custom role. 有关详细信息,请参阅控制对资源的访问For more information see, Control access to resources.

计算群集的托管标识Managed identity with compute cluster

有关详细信息,请参阅为计算群集设置托管标识For more information, see Set up managed identity for compute cluster.

使用交互式身份验证Use interactive authentication

重要

交互式身份验证使用浏览器并需要 Cookie(包括第三方 Cookie)。Interactive authentication uses your browser, and requires cookies (including 3rd party cookies). 如果已禁用 Cookie,则可能会收到“我们无法为你登录”之类的错误。If you have disabled cookies, you may receive an error such as "we couldn't sign you in." 如果已启用 Azure 多重身份验证,则也可能出现此错误。This error may also occur if you have enabled Azure multi-factor 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")

使用 Azure CLI 时,可使用 az login 命令对 CLI 会话进行身份验证。When using the Azure CLI, the az login command is used to authenticate the CLI session. 有关详细信息,请参阅 Azure CLI 入门For more information, see Get started with Azure CLI.

提示

如果你从之前使用 Azure CLI 以交互方式进行身份验证的环境中使用 SDK,则可通过 CLI 缓存的凭据使用 AzureCliAuthentication 类对工作区进行身份验证:If you are using the SDK from an environment where you have previously authenticated interactively using the Azure CLI, you can use the AzureCliAuthentication class to authenticate to the workspace using the credentials cached by the CLI:

from azureml.core.authentication import AzureCliAuthentication
cli_auth = AzureCliAuthentication()
ws = Workspace(subscription_id="your-sub-id",
               resource_group="your-resource-group-id",
               workspace_name="your-workspace-name",
               auth=cli_auth
               )

使用服务主体身份验证Use service principal authentication

若要从 SDK 中使用服务主体向工作区进行身份验证,请使用 ServicePrincipalAuthentication 类构造函数。To authenticate to your workspace from the SDK, using a 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.chinacloudapi.cn/';
const tenantId = 'your-tenant-id';
const authorityUrl = authorityHostUrl + tenantId;
const clientId = 'your-client-id';
const clientSecret = 'your-client-secret';
const resource = 'https://management.chinacloudapi.cn/';

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.chinacloudapi.cn/',
    accessToken: "random-oauth-token",
    isMRRT: true,
    _clientId: 'your-client-id',
    _authority: 'https://login.chinacloudapi.cn/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.chinacloudapi.cn"
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.chinacloudapi.cn/", 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.chinacloudapi.cn/',
    'accessToken': 'random-oauth-token',
    'isMRRT': True,
    '_clientId': 'your-client-id',
    '_authority': 'https://login.chinacloudapi.cn/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.

JavaJava

在 Java 中,使用标准 REST 调用检索持有者令牌:In Java, retrieve the bearer token using a standard REST call:

String tenantId = "your-tenant-id";
String clientId = "your-client-id";
String clientSecret = "your-client-secret";
String resourceManagerUrl = "https://management.azure.com";

HttpRequest tokenAuthenticationRequest = tokenAuthenticationRequest(tenantId, clientId, clientSecret, resourceManagerUrl);

HttpClient client = HttpClient.newBuilder().build();
Gson gson = new Gson();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode == 200)
{
     body = gson.fromJson(body, AuthenticationBody.class);

    // ... etc ... 
}
// ... etc ...

static HttpRequest tokenAuthenticationRequest(String tenantId, String clientId, String clientSecret, String resourceManagerUrl){
    String authUrl = String.format("https://login.microsoftonline.com/%s/oauth2/token", tenantId);
    String clientIdParam = String.format("client_id=%s", clientId);
    String resourceParam = String.format("resource=%s", resourceManagerUrl);
    String clientSecretParam = String.format("client_secret=%s", clientSecret);

    String bodyString = String.format("grant_type=client_credentials&%s&%s&%s", clientIdParam, resourceParam, clientSecretParam);

    HttpRequest request = HttpRequest.newBuilder()
            .uri(URI.create(authUrl))
            .POST(HttpRequest.BodyPublishers.ofString(bodyString))
            .build();
    return request;
}

class AuthenticationBody {
    String access_token;
    String token_type;
    int expires_in;
    String scope;
    String refresh_token;
    String id_token;
    
    AuthenticationBody() {}
}

前面的代码需要处理除 200 OK 以外的异常和状态代码,但会显示模式:The preceding code would have to handle exceptions and status codes other than 200 OK, but shows the pattern:

  • 使用客户端 ID 和密码来验证你的程序是否应具有访问权限Use the client ID and secret to validate that your program should have access
  • 使用租户 ID 指定 login.microsoftonline.com 应查找的位置Use your tenant ID to specify where login.microsoftonline.com should be looking
  • 使用 Azure 资源管理器作为授权令牌的源Use Azure Resource Manager as the source of the authorization token

使用托管标识身份验证Use managed identity authentication

若要从配置有托管标识的 VM 或计算群集对工作区进行身份验证,请使用 MsiAuthentication 类。To authenticate to the workspace from a VM or compute cluster that is configured with a managed identity, use the MsiAuthentication class. 以下示例演示如何使用此类对工作区进行身份验证:The following example demonstrates how to use this class to authenticate to a workspace:

from azureml.core.authentication import MsiAuthentication

msi_auth = MsiAuthentication()

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

后续步骤Next steps