你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

编写客户端应用验证码

设置 Azure 数字孪生实例和身份验证后,可创建将用于与实例进行交互的客户端应用程序。 设置入门客户端项目后,需要针对 Azure 数字孪生实例在该客户端应用中编写代码以对应用进行身份验证

Azure 数字孪生使用 基于 OAUTH 2.0 的 Microsoft Entra 安全令牌进行身份验证。 若要对 SDK 进行身份验证,需要获取具有 Azure 数字孪生正确权限的持有者令牌,并将其与 API 调用一起传递。

本文介绍如何使用 Azure.Identity 客户端库获取凭据。 尽管本文介绍的是 C# 代码示例(例如你为 .NET (C#) SDK 编写的内容),但无论你使用的是何种 SDK,都可以使用 Azure.Identity 版本(有关可用于 Azure 数字孪生的 SDK 的详细信息,请参阅 Azure 数字孪生 API 和 SDK)。

先决条件

首先,请完成设置实例和身份验证中的设置步骤。 此设置将确保你拥有 Azure 数字孪生实例,并且你的用户具有访问权限。 完成此设置后,便可编写客户端应用代码。

若要继续,你需要一个可在其中编写代码的客户端应用项目。 如果尚未设置客户端应用项目,请使用你选择的语言创建一个基本项目,以在本教程中使用。

使用 Azure.Identity 库进行身份验证

Azure.Identity 是一个客户端库,提供多种凭据获取方法,你可使用这些方法来获取持有者令牌并对 SDK 进行身份验证。 尽管本文提供的是 C# 示例,但你可查看多种语言的 Azure.Identity,其中包括:

Azure.Identity 中的三种常用凭据获取方法是:

  • DefaultAzureCredential 为即将部署到 Azure 的应用程序提供默认的 TokenCredential 身份验证流,若在本地部署,建议选择此方法。 还可启用它来尝试本文中建议的另外两种方法;它包装 ManagedIdentityCredential 并可使用配置变量访问 InteractiveBrowserCredential
  • 在需要托管标识(MSI)的情况下,ManagedIdentityCredential 非常有效,非常适合使用 Azure Functions 并部署到 Azure 服务。
  • InteractiveBrowserCredential 适用于交互式应用程序,可用于创建经过身份验证的 SDK 客户端。

本文的余下内容演示如何在 .NET (C#) SDK 中使用这些方法。

向 .NET 项目添加 Azure.Identity

若要将 .NET 项目设置为使用 Azure.Identity 进行身份验证,请完成以下步骤:

  1. 将 SDK 包 Azure.DigitalTwins.CoreAzure.Identity 包包含在项目中。 可使用 Visual Studio 包管理器或 dotnet 命令行工具包含这些包,具体取决于你选择的工具。

  2. 向项目代码添加以下 using 语句:

    using Azure.DigitalTwins.Core;
    using Azure.Identity;
    using System;
    

然后,添加代码以使用 Azure.Identity 中的某个方法来获取凭据。 以下各部分将更详细地介绍每一种方法的使用。

DefaultAzureCredential 方法

DefaultAzureCredential 为即将部署到 Azure 的应用程序提供默认的 TokenCredential 身份验证流,若在本地部署,建议选择此方法

若要使用默认的 Azure 凭据,则需要 Azure 数字孪生实例的 URL(查找说明)。

下面是向项目添加 DefaultAzureCredential 的代码示例:

public class DefaultAzureCredentialSample
{
    // The URL of your instance, starting with the protocol (https://)
    private const string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-URL>";

    internal void RunSample()
    {
        //...

        DigitalTwinsClient client;
        try
        {
            var credential = new DefaultAzureCredential();
            client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);
        }
        catch (Exception e)
        {
            Console.WriteLine($"Authentication or client creation error: {e.Message}");
            Environment.Exit(0);
        }
    }
}

注意

当前存在影响 DefaultAzureCredential 包装类的已知问题,该问题在进行身份验证时可能会导致错误。 如果遇到此问题,可以尝试使用以下可选参数实例化 DefaultAzureCredential 来解决问题:new DefaultAzureCredential(new DefaultAzureCredentialOptions { ExcludeSharedTokenCacheCredential = true });

有关此问题的详细信息,请参阅 Azure 数字孪生已知问题

设置本地 Azure 凭据

使用 DefaultAzureCredential,此示例将在本地环境中搜索凭据,如本地 DefaultAzureCredential 或 Visual Studio/Visual Studio Code 中的 Azure 登录。 因此,应该通过这些机制在本地登录 Azure,以便设置示例的凭据。

如果使用 Visual Studio 或 Visual Studio Code 运行代码示例,请确保使用要用于访问 Azure 数字孪生实例的相同 Azure 凭据登录到该编辑器。 如果使用本地 CLI 窗口,请运行 az login 命令来登录到你的 Azure 帐户。 此后,当你运行代码示例时,系统应自动对你进行身份验证。

ManagedIdentityCredential 方法

在需要托管标识(MSI)的情况下,ManagedIdentityCredential 方法非常有效,例如,使用 Azure Functions 进行身份验证时

这意味着,可以在与项目相同的项目中DefaultAzureCredential使用ManagedIdentityCredential,或者InteractiveBrowserCredential,对项目的不同部分进行身份验证。

若要使用默认的 Azure 凭据,则需要 Azure 数字孪生实例的 URL(查找说明)。 你可能还需要应用注册和应用注册的应用程序(客户端)ID

在 Azure 函数中,可使用如下所示的托管标识凭据:

public class ManagedIdentityCredentialSample
{
    // The URL of your instance, starting with the protocol (https://)
    private const string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-URL>";

    internal void RunSample()
    {
        DigitalTwinsClient client;
        try
        {
            // To use the function app's system-assigned identity:
            ManagedIdentityCredential cred = new ManagedIdentityCredential();
            // To use a user-assigned identity for the function app:
            //ManagedIdentityCredential cred = new ManagedIdentityCredential("<uai-client-ID>");

            client = new DigitalTwinsClient(new Uri(adtInstanceUrl), cred);
        }
        catch (Exception e)
        {
            Console.WriteLine($"Authentication or client creation error: {e.Message}");
            Environment.Exit(0);
        }
    }
}

创建凭据时,将参数留空,如上所示,将返回函数应用的系统分配标识的凭据(如果有)。 若要改为指定用户分配的标识,请将用户分配的标识的 客户端 ID 传递到参数中。

InteractiveBrowserCredential 方法

InteractiveBrowserCredential 方法适用于交互式应用程序,并将打开一个 Web 浏览器进行身份验证。 如果需要交互式身份验证,可使用此方法而不是 DefaultAzureCredential

若要使用交互式浏览器凭据,你将需要具有 Azure 数字孪生 API 权限的应用注册。 有关如何设置此应用注册的步骤,请参阅使用 Azure 数字孪生访问 (CLI) 创建应用注册。 设置应用注册后,需要以下内容:

下面是使用 InteractiveBrowserCredential 创建经过身份验证的 SDK 客户端的代码示例。

public class InteractiveBrowserCredentialSample
{
    // Your client / app registration ID
    private const string clientId = "<your-client-ID>";
    // Your tenant / directory ID
    private const string tenantId = "<your-tenant-ID>";
    // The URL of your instance, starting with the protocol (https://)
    private const string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-URL>";

    internal void RunSample()
    {
        //...

        DigitalTwinsClient client;
        try
        {
            var credential = new InteractiveBrowserCredential(tenantId, clientId);
            client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);
        }
        catch (Exception e)
        {
            Console.WriteLine($"Authentication or client creation error: {e.Message}");
            Environment.Exit(0);
        }
    }
}

注意

虽然你可将客户端 ID、租户 ID 和实例 URL 直接放置在代码中(如上所示),但建议让代码从配置文件或环境变量中获取这些值。

使用 Azure Functions 进行身份验证

本部分包含使用 Azure Functions 进行身份验证上下文中的一些重要配置选项。 首先,你将了解建议的类级别变量和验证码,使函数可以访问 Azure 数字孪生。 然后,你将了解在函数的代码发布到 Azure 后要完成的最后一些函数的配置步骤。

编写应用程序代码

编写 Azure 函数时,请考虑将以下变量和代码添加到函数:

  • 用于将 Azure 数字孪生服务 URL 读作环境变量或配置设置的代码。 最好从应用程序设置/环境变量读取服务 URL,而不是在函数中对其进行硬编码。 在 Azure 函数中,用于读取环境变量的代码可能如下所示:

    private static readonly string adtInstanceUrl = Environment.GetEnvironmentVariable("ADT_SERVICE_URL");
    

    稍后,在发布函数后,你将创建并设置环境变量的值,供此代码读取。 有关如何执行此操作的说明,请跳到配置应用程序设置

  • 用于保存 HttpClient 实例的静态变量。 HttpClient 的创建成本相对较高,因此你可能希望使用验证码创建一次,以避免在每次调用函数时创建。

    private static readonly HttpClient singletonHttpClientInstance = new HttpClient();
    
  • 托管标识凭据。 创建一个托管标识凭据,函数将使用该凭据访问 Azure 数字孪生。

    // To use the function app's system-assigned identity:
    var cred = new ManagedIdentityCredential();
    // To use a user-assigned identity for the function app:
    //var cred = new ManagedIdentityCredential("<uai-client-ID>");
    

    将参数留空(如上所示)将返回函数应用的系统分配标识的凭据(如果有)。 若要改为指定用户分配的标识,请将用户分配的标识的 客户端 ID 传递到参数中。

    稍后,在发布函数后,你将确保函数的标识有权访问 Azure 数字孪生 API。 有关如何执行此操作的说明,请跳到分配访问角色

  • 本地变量 DigitalTwinsClient 在函数内添加该变量,用于保存 Azure 数字孪生客户端实例。 请勿在类中将此变量设置为静态。

    var client = new DigitalTwinsClient(
        new Uri(adtInstanceUrl),
        cred,
        new DigitalTwinsClientOptions
        {
            Transport = new HttpClientTransport(singletonHttpClientInstance)
        });
    
  • 对 adtInstanceUrl 的 NULL 检查 添加 NULL 检查,然后将函数逻辑包装在 try/catch 块中以捕获所有异常。

将这些变量添加到函数后,函数代码可能如以下示例所示。

// Default URL for triggering event grid function in the local environment.
// http://localhost:7071/runtime/webhooks/EventGrid?functionName={functionname}
//<Function_dependencies>
using Azure.Core.Pipeline;
using Azure.DigitalTwins.Core;
using Azure.Identity;
using Azure.Messaging.EventGrid;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.EventGrid;
using Microsoft.Extensions.Logging;
using System;
using System.Net.Http;
//</Function_dependencies>

namespace DigitalTwins_Samples
{
    public class DigitalTwinsIngestFunctionSample
    {
        // Your Digital Twin URL is stored in an application setting in Azure Functions
        // <ADT_service_URL>
        private static readonly string adtInstanceUrl = Environment.GetEnvironmentVariable("ADT_SERVICE_URL");
        // </ADT_service_URL>
        // <HTTP_client>
        private static readonly HttpClient singletonHttpClientInstance = new HttpClient();
        // </HTTP_client>

        [FunctionName("TwinsFunction")]
        public void Run([EventGridTrigger] EventGridEvent eventGridEvent, ILogger log)
        {
            log.LogInformation(eventGridEvent.Data.ToString());
            if (adtInstanceUrl == null) log.LogError("Application setting \"ADT_SERVICE_URL\" not set");
            try
            {
                // Authenticate with Digital Twins
                // <ManagedIdentityCredential>
                // To use the function app's system-assigned identity:
                var cred = new ManagedIdentityCredential();
                // To use a user-assigned identity for the function app:
                //var cred = new ManagedIdentityCredential("<uai-client-ID>");
                // </ManagedIdentityCredential>
                // <DigitalTwinsClient>
                var client = new DigitalTwinsClient(
                    new Uri(adtInstanceUrl),
                    cred,
                    new DigitalTwinsClientOptions
                    {
                        Transport = new HttpClientTransport(singletonHttpClientInstance)
                    });
                // </DigitalTwinsClient>
                log.LogInformation($"ADT service client connection created.");

                // Add your business logic here.
            }
            catch (Exception e)
            {
                log.LogError(e.Message);
            }
        }
    }
}

完成函数代码后(包括添加身份验证和函数逻辑),将应用发布到 Azure

配置已发布的应用

最后,为已发布的 Azure 函数完成以下配置步骤,以确保该函数可以访问 Azure 数字孪生实例。

Azure Cloud Shell本地 Azure CLI 中运行以下命令。

注意

此部分必须由有权管理用户对 Azure 资源的用户访问权限(包括授予和委派权限)的 Azure 用户完成。 满足此要求的常见角色包括“所有者”、“帐户管理员”或“用户访问管理员”和“参与者”的组合。 有关 Azure 数字孪生角色的权限要求的详细信息,请参阅设置实例和身份验证

分配访问角色

Azure 函数需要将持有者令牌传递给它。 为确保传递了持有者令牌,请为函数应用授予 Azure 数字孪生实例的“Azure 数字孪生数据所有者”角色,这将授予函数应用在实例上执行数据平面活动的权限

  1. 使用以下命令为函数创建系统托管标识(如果该函数已有一个,此命令将输出其详细信息)。 记下输出中的 principalId 字段。 你将使用此 ID 来引用函数,以便可以在下一步中授予其权限。

    az functionapp identity assign --resource-group <your-resource-group> --name <your-function-app-name>	
    
  2. 使用以下命令中的 principalId 值为函数赋予 Azure 数字孪生实例的“Azure 数字孪生数据所有者”角色

    az dt role-assignment create --dt-name <your-Azure-Digital-Twins-instance> --assignee "<principal-ID>" --role "Azure Digital Twins Data Owner"
    

配置应用程序设置

接下来,通过为其设置 环境变量 ,使 Azure 数字孪生实例的 URL 可供函数访问。

提示

通过将 https:// 添加到实例主机名的开头,创建 Azure 数字孪生实例的 URL。 若要查看主机名以及实例的所有属性,请运行 az dt show --dt-name <your-Azure-Digital-Twins-instance>

以下命令为实例的 URL 设置环境变量,函数在需要访问实例时将使用该环境变量。

az functionapp config appsettings set --resource-group <your-resource-group> --name <your-function-app-name> --settings "ADT_SERVICE_URL=https://<your-Azure-Digital-Twins-instance-host-name>"

跨租户进行身份验证

Azure 数字孪生是一项仅支持一个 Microsoft Entra 租户的服务:Azure 数字孪生实例所在的订阅的主租户。

因此,向 Azure 数字孪生 API 发出的请求需要一个用户或服务主体,并且该用户或服务主体应属于 Azure 数字孪生实例所驻留的同一租户。 为防止恶意扫描 Azure 数字孪生终结点,对于来自源租户外部的具有访问令牌的请求,会返回“404 子域未找到”错误消息。 即使用户或服务主体通过 Microsoft Entra B2B 协作获得了 Azure 数字孪生数据所有者或 Azure 数字孪生数据读取者角色,也会返回此错误。

如果需要使用属于实例中不同租户的服务主体或用户帐户来访问 Azure 数字孪生实例,可以让其他租户的每个联合标识从 Azure 数字孪生实例的“主”租户请求令牌

执行此操作的一种方法是使用以下 CLI 命令,其中 <home-tenant-ID> 是包含 Azure 数字孪生实例的 Microsoft Entra 租户的 ID:

az account get-access-token --tenant <home-tenant-ID> --resource https://digitaltwins.azure.net

请求此项后,标识将收到为 https://digitaltwins.azure.net Microsoft Entra 资源颁发的令牌,该令牌具有与 Azure 数字孪生实例的匹配租户 ID 声明。 如果在 API 请求或 Azure.Identity 代码中使用此令牌,应该可以使用联合标识访问 Azure 数字孪生资源。

还可以在代码的凭据选项中指定主租户。

以下示例演示如何在 DefaultAzureCredential 选项中设置 InteractiveBrowserTenantId 的示例租户 ID 值:

public class DefaultAzureCredentialOptionsSample
{
    // The URL of your instance, starting with the protocol (https://)
    private const string adtInstanceUrl = "https://<your-Azure-Digital-Twins-instance-URL>";

    private static DefaultAzureCredentialOptions credentialOptions = new DefaultAzureCredentialOptions()
    {
        ExcludeSharedTokenCacheCredential = true,
        ExcludeVisualStudioCodeCredential = true,
        TenantId = "<your-Azure-Active-Directory-tenant-ID>"
    };

    private static DefaultAzureCredential credential = new DefaultAzureCredential(credentialOptions);

    DigitalTwinsClient client = new DigitalTwinsClient(new Uri(adtInstanceUrl), credential);
}

有类似的选项可用于为租户设置对 Visual Studio 和 Visual Studio Code 的身份验证。 有关可用选项的详细信息,请参阅 DefaultAzureCredentialOptions 文档

其他凭据方法

如果上面突出显示的身份验证方案不能满足你的应用需求,可浏览 Microsoft 标识平台中提供的其他类型的身份验证。 此平台的文档介绍了按应用程序类型组织的更多身份验证方案。

后续步骤

详细了解 Azure 数字孪生中安全性的工作原理:

或者,现在身份验证已设置,接下来请在实例中创建和管理模型: