你当前正在访问 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
进行身份验证,请完成以下步骤:
将 SDK 包
Azure.DigitalTwins.Core
和Azure.Identity
包包含在项目中。 可使用 Visual Studio 包管理器或dotnet
命令行工具包含这些包,具体取决于你选择的工具。向项目代码添加以下 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
,此示例将在本地环境中搜索凭据,如本地 Azure CLI 或 Visual Studio/Visual Studio Code 中的 Azure 登录。 因此,应该通过这些机制在本地登录 Azure,以便设置示例的凭据。
如果使用 Visual Studio 或 Visual Studio Code 运行代码示例,请确保使用要用于访问 Azure 数字孪生实例的相同 Azure 凭据登录到该编辑器。 如果使用本地 CLI 窗口,请运行 az login
命令来登录到你的 Azure 帐户。 登录后,运行代码示例时,应会自动进行身份验证。
ManagedIdentityCredential 方法
在需要托管标识(MSI)的情况下,ManagedIdentityCredential 方法非常有效,例如,使用 Azure Functions 进行身份验证时。
在同一个项目中,您可以与DefaultAzureCredential
或InteractiveBrowserCredential
一起使用ManagedIdentityCredential
,以对项目的不同部分进行身份验证。
若要使用 Azure 默认凭据,您需要 Azure 数字孪生实例的 URL(查找此 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”传递到构造函数的 参数中id
。
InteractiveBrowserCredential 方法
InteractiveBrowserCredential 方法适用于交互式应用程序,并启动 Web 浏览器进行身份验证。 当您需要交互式身份验证时,使用此方法,而不是 DefaultAzureCredential
。
若要使用交互式浏览器凭据,你需要具有 Azure 数字孪生 API 权限的应用注册。 有关如何设置此应用注册的步骤,请参阅 使用 Azure 数字孪生访问创建应用注册。 设置应用注册后,需要以下值:
下面是使用 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”传递到构造函数的 参数中
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 数字孪生数据所有者 角色,该角色为函数应用授予对实例执行数据平面活动的权限。
使用以下命令为函数创建 系统托管标识 (如果该函数已有一个,此命令将输出其详细信息)。 记下输出中的
principalId
字段。 你将使用此 ID 来引用函数,以便可以在下一步中授予其权限。az functionapp identity assign --resource-group <your-resource-group> --name <your-function-app-name>
使用以下命令中的
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 数字孪生资源。
还可以在代码的凭据选项中指定主租户。
以下示例演示如何在 InteractiveBrowserTenantId
选项中设置 DefaultAzureCredential
的示例租户 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 数字孪生中的安全性的工作原理,请参阅:
或者,现在身份验证已设置,接下来请在实例中创建和管理模型: