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

AppAuthentication 到 Azure.Identity 迁移指南

当 Microsoft.Azure.Services.AppAuthentication 库于 2017 年秋季首次发布时,它专门用于帮助缓解源代码中凭据的常见和系统性问题。 它引入了一 种新的应用开发范例 ,允许开发人员编写代码一次,并允许 AppAuthentication 客户端库确定如何基于应用程序环境进行身份验证 - 无论是在使用开发人员帐户的开发人员工作站上,还是在 Azure 中使用托管服务标识进行部署。 开发人员可以完全避免直接处理凭据,既可以简化开发,又通过防止凭据在源代码中意外泄露来提高安全性。 鉴于其简单和安全优势, AppAuthentication 受到开发人员的好评。 NuGet 收到了超过 1.6 亿次下载,并用于 Azure 服务的其他库和框架,例如 .NET Core 中的 Azure 密钥保管库 配置提供程序Microsoft.Azure.ServiceBus SDK。

Azure.Identity 客户端库于 2019 年秋季发布,是该库的精神AppAuthentication继任者。 Azure.Identity 具有一个主要优势 AppAuthentication ,因为它在多种语言中具有更广泛的可用性,这些语言提供一致的设计和类似的用法,而 AppAuthentication 仅适用于 .NET。 除了支持多种语言外,Azure.Identity 的一项关键设计功能是其抽象 TokenCredential 类的各种实现, 较新的 Azure 客户端 SDK 接受这些类。 这些较新的 Azure SDK 可通过以“Azure”开头的包名称和命名空间(即“Azure.Identity”、“Azure.Storage.Blobs”)轻松区分。 若要进行身份验证,需要实例化所需的 TokenCredential 对象类型,并直接传递到 Azure SDK 客户端类。 与使用 AppAuthentication 和需要指定访问令牌的较旧 SDK,此设计为使用 Azure.Identity 提供了额外的安全优势,因为访问令牌不需要由应用程序本身直接处理。 这可降低通过跟踪、日志和其他源意外泄露访问令牌的额外风险。

如果要开始开发新应用程序,强烈建议使用 Azure.Identity 和新的 Azure 客户端 SDK。 如果现有应用程序使用 AppAuthentication 并想要使用 Azure.Identity,则首选路径是将应用程序更新为使用支持接受 TokenCredentials 的新 Azure 客户端 SDK。 AppAuthentication 现在被视为已弃用,并且不会对其开发进行进一步投资。 DefaultAzureCredential使用 中的 Azure.Identity 将提供与 中AppAuthentication类似的功能AzureServiceTokenProvider,其中使用的身份验证提供程序将根据当前环境而更改。 如果使用 对特定身份验证提供程序使用AppAuthenticationAppAuthentication连接字符串,请参阅下表,了解如何通过在 Azure.Identity 中创建相应的 TokenCredential 来使用相同的身份验证提供程序。

身份验证提供程序 AppAuthentication
连接字符串
Azure.Identity
TokenCredential
(基于环境的默认) 默认值 - 未使用连接字符串 new DefaultAzureCredential () *
Azure CLI RunAs=Developer;
DeveloperTool=AzureCli
new AzureCliCredential ()
Visual Studio RunAs=Developer;DeveloperTool=VisualStudio new VisualStudioCredential ()
Windows 集成身份验证 RunAs=CurrentUser 不支持
系统分配的托管标识 RunAs=App new ManagedIdentityCredential ()
用户分配的托管标识 RunAs=App;AppId=appId 新的 ManagedIdentityCredential (appId)
服务主体客户端证书 RunAs=App;AppId=appId;
KeyVaultCertificateSecretIdentifier=kvIdentifier
不支持
服务主体客户端证书 RunAs=App;AppId=appId;TenantId=tenantId;
CertificateThumbprint=thumbprint;
CertificateStoreLocation=location
new EnvironmentCredential () **
new ClientCertificateCredential (tenantId、appId、certObjOrFilePath)
服务主体客户端证书 RunAs=App;AppId=appId;TenantId=tenantId;
CertificateSubjectName=subject;
CertificateStoreLocation=location
new EnvironmentCredential () **
new ClientCertificateCredential (tenantId、appId、certObjOrFilePath)
服务主体客户端密码 RunAs=App;AppId=appId;TenantId=tenantId;
AppKey=secret
new EnvironmentCredential () **
new ClientSecretCredential (tenantId、appId、secret)

注意

*AzureServiceTokenProviderDefaultAzureCredential 之间的身份验证提供程序和顺序不同
** 需要设置 环境变量

虽然 Azure.Identity 支持 AppAuthentication 提供的大多数身份验证方案和提供程序,但目前尚不支持某些方案和功能:

  • Windows 集成身份验证提供程序

  • System.Data.SqlClient.SqlAuthenticationProvider 实现 (SqlAppAuthenticationProvider)

    • 对于 Microsoft.Data.SqlClient,请参阅 Active Directory 默认身份验证。 此身份验证模式提供的功能类似,其中 DefaultAzureCredential 用于获取访问令牌以对 SQL 实例进行身份验证。
  • 直接使用证书存储中的证书作为客户端凭据 (使用者名称或指纹标识符)

  • 直接使用 密钥保管库 中的证书作为客户端凭据 (使用密钥保管库证书机密标识符)

  • 使用环境配置 (更改身份验证提供程序,即 AppAuthentication) 中的连接字符串

    • 使用 DefaultAzureCredential 和 EnvironmentCredential 的 Azure.Identity 中的有限支持,请参阅 环境变量
  • 确定用于基于环境的身份验证的身份验证提供程序和标识 (即 AzureServiceTokenProvider.PrincipalUsed 属性)

    • 可以使用 AzureEventSourceListener 确定与 Azure.Identity 中 DefaultAzureCredential 一起使用的身份验证提供程序

下面是使用 AppAuthentication 从较旧的 Azure 客户端 SDK 迁移到使用 Azure.Identity 的较新版本的 Azure 客户端 SDK 的一些示例。 使用 Azure.Identity 的代码通常比 AppAuthentication 代码更直接和简单

Microsoft.Azure.KeyVault 到 Azure.Security.KeyVault:

  • 使用 AppAuthentication
AzureServiceTokenProvider tokenProvider = new AzureServiceTokenProvider();
var client = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(tokenProvider.KeyVaultTokenCallback));
var secretBundle = await client.GetSecretAsync("https://keyvaultname.vault.azure.net/secrets/secretname");

Console.WriteLine(secretBundle.Value);
  • 使用 Azure.Identity
var client = new SecretClient(new Uri("https://keyvaultname.vault.azure.net"), new DefaultAzureCredential());
var secret = client.GetSecret("secretName").Value;

Console.WriteLine(secret.Value);

Microsoft.Azure.Storage.Queues 到 Azure.Storage.Queues:

  • 使用 AppAuthentication
var tokenProvider = new AzureServiceTokenProvider();
var accessToken = await tokenProvider.GetAccessTokenAsync("https://storageaccountname.queue.core.windows.net");

var tokenCredential = new StorageTokenCredential(accessToken);
var storageCredentials = new StorageCredentials(tokenCredential);

var uri = new StorageUri(new Uri("https://storageaccountname.queue.core.windows.net"));
var client = new CloudQueueClient(uri, storageCredentials);

var queue = client.GetQueueReference("queuename");
queue.AddMessage(new CloudQueueMessage("Microsoft.Azure.Storage.Queues"));
  • 使用 Azure.Identity
QueueClient queueClient = new QueueClient(new Uri("https://storageaccountname.queue.core.windows.net/queuename"), new DefaultAzureCredential());
queueClient.SendMessage("Azure.Storage.Queues");

访问令牌检索

  • 使用 AppAuthentication
var tokenProvider = new AzureServiceTokenProvider();
var accessToken = await tokenProvider.GetAccessTokenAsync(ResourceId);
  • 使用 Azure.Identity
var tokenCredential = new DefaultAzureCredential();
var accessToken = await tokenCredential.GetTokenAsync(
    new TokenRequestContext(scopes: new string[] { ResourceId + "/.default" }) { }
);

注意

在此处找到有关.default范围的详细信息。