Microsoft.Identity.Web 凭据概述

当应用程序使用Microsoft 标识平台进行身份验证时,它会提供一个凭据来证明其标识。 Microsoft。Identity.Web 支持多种凭据类型,每种类型都适合不同的环境和安全要求。

本文可帮助你了解可用的凭据类型,为方案选择合适的凭据,并在应用程序中配置凭据。

为什么凭据选择很重要

应用程序使用的凭据直接影响其安全状况、操作开销和部署灵活性。 选择不佳的凭据可能会公开机密、需要手动轮换或限制应用程序可以运行的位置。

Microsoft。Identity.Web 提供了统一的配置模型,可让你:

  • 指定多个凭据,并启用自动切换功能。
  • 在不修改应用程序代码的情况下更改凭据类型。
  • 在不同的环境(开发、测试、生产)中使用不同的凭据。

支持的凭据类型

Microsoft。Identity.Web 支持机密客户端应用程序的三类凭据:

无证书凭据(联合身份凭据 + 托管身份)

无证书凭据使用Azure托管标识与联合标识凭据(FIC)结合使用来对应用程序进行身份验证,而无需管理任何机密或证书。 Azure完全处理凭据生命周期。

其工作原理:应用程序使用其托管标识来获取令牌,而 Microsoft 身份平台通过预先配置的联合信任接收该令牌,以此证明应用程序的身份。

最佳适用:在 Azure 上运行的生产工作负荷。

详细了解无证书身份验证

证书

证书提供强非对称基于密钥的身份验证。 应用程序通过使用证书的私钥对断言进行签名来验证其身份。 Microsoft。Identity.Web 可以从多个源加载证书:

  • Azure 密钥保管库 - 具有访问策略的集中式托管证书存储。
  • Certificate Store - Windows证书存储(CurrentUser 或 LocalMachine)。
  • 文件路径 - 磁盘上的证书文件(.pfx 格式)。
  • Base64 编码 - 直接嵌入在配置中的证书。

最适合: 无法使用无证书身份验证或混合环境的生产工作负载。

详细了解证书凭据

客户端机密

客户端机密是应用程序向Microsoft 标识平台呈现的共享字符串。 它们是配置的最简单凭据类型,但提供最弱的安全性。

最适合: 仅本地开发和测试。

详细了解客户端机密


选择正确的凭据类型

使用以下决策树来确定哪种凭据类型适合你的方案。

Is your application running on Azure?
├── Yes
│   ├── Can you use Managed Identity?
│   │   ├── Yes → Use certificateless credentials (recommended)
│   │   └── No → Use certificates from Azure Key Vault
└── No
    ├── Is this a production environment?
    │   ├── Yes → Use certificates (Key Vault, Certificate Store, or file path)
    │   └── No → Use client secrets for development/testing

通用指南

选择凭据类型时,请遵循以下原则:

  • 当应用程序在 Azure 上运行时,Always 首选无证书凭据。 它们完全消除了凭据管理。
  • 当无证书凭据不可用时使用证书。 尽可能将它们存储在Azure 密钥保管库中。
  • 将客户端机密限于开发环境。 切勿在生产部署中使用客户端机密。

比较凭据类型

下表总结了凭据类型之间的主要差异:

特性 无证书 (FIC + MI) 证书 客户端机密
安全级别 最高
机密暴露风险 无 - 没有可泄露的机密 低 - 私钥受保护 高 - 可以复制字符串
需要轮换 否 - Azure管理生命周期 是 - 证书到期前 是 - 密钥到期前
旋转复杂性 没有 中 - 更新证书,重新部署 低 - 更新字符串,重新部署
Azure 门户设置 托管标识 + FIC 信任 将证书上传到应用注册 在应用注册中生成机密
合适的环境 Azure生产环境 任何生产环境 仅开发和测试
基础结构依赖项 Azure计算资源 证书存储或密钥保管库 没有
遵从性 满足零信任要求 满足大多数合规性框架 可能无法满足安全策略

在 appsettings.json 中配置凭据

Microsoft。Identity.Web 在配置中使用 ClientCredentials 数组来指定一个或多个凭据。 数组中的每个条目都包含一个 SourceType 属性,该属性指示凭据的来源。

配置结构

以下示例演示了具有单个无证书凭据的最小配置:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-client-id",

    "ClientCredentials": [
      {
        "SourceType": "SignedAssertionFromManagedIdentity",
        "ManagedIdentityClientId": "user-assigned-managed-identity-client-id"
      }
    ]
  }
}

SourceType 值

SourceType 属性对应于 CredentialSource 枚举,并确定 Microsoft.Identity.Web 如何加载凭据。

SourceType 值 凭据类型 说明
SignedAssertionFromManagedIdentity 无证书 使用托管标识获取已签名断言。 建议用于 Azure 生产环境。
KeyVault 证书 按 URI 从Azure 密钥保管库加载证书。
StoreWithThumbprint 证书 通过指纹从 Windows 证书库中加载一个证书。
StoreWithDistinguishedName 证书 从Windows证书存储中按主题专有名称加载证书。
Path 证书 从磁盘上的 .pfx 文件加载证书。
Base64Encoded 证书 在配置中从 Base64 编码的字符串加载证书。
ClientSecret 客户端密码 使用客户端机密字符串。
AutoDecryptKeys 令牌解密 自动检索用于解密加密令牌的密钥。
SignedAssertionFilePath 联合 从文件路径读取签名声明(用于 Kubernetes 工作负载身份验证)。

按类型排序的凭据示例

以下示例演示如何在appsettings.json中配置每种凭据类型,并在可用时提供 C# 代码示例。

无证书(托管标识)

通过指定其客户端 ID 来使用一个用户指定的托管标识:

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-client-id",
    "ClientCredentials": [
      {
        "SourceType": "SignedAssertionFromManagedIdentity",
        "ManagedIdentityClientId": "user-assigned-managed-identity-client-id"
      }
    ]
  }
}

对于系统分配的托管标识,请省略属性 ManagedIdentityClientId

{
  "AzureAd": {
    "ClientCredentials": [
      {
        "SourceType": "SignedAssertionFromManagedIdentity"
      }
    ]
  }
}

来自Azure 密钥保管库的证书

通过指定保管库 URL 和证书名称来加载存储在Azure 密钥保管库中的证书:

{
  "AzureAd": {
    "ClientCredentials": [
      {
        "SourceType": "KeyVault",
        "KeyVaultUrl": "https://your-keyvault.vault.azure.net",
        "KeyVaultCertificateName": "your-certificate-name"
      }
    ]
  }
}

还可以在 C# 中使用 CredentialDescription 帮助程序方法:

var credential = CredentialDescription.FromKeyVault(
    "https://your-keyvault.vault.azure.net",
    "your-certificate-name");

证书存储中的证书

按指纹从Windows证书存储加载证书:

{
  "AzureAd": {
    "ClientCredentials": [
      {
        "SourceType": "StoreWithThumbprint",
        "CertificateThumbprint": "ABC123DEF456...",
        "CertificateStorePath": "CurrentUser/My"
      }
    ]
  }
}

还可以使用可分辨名称,这简化了证书轮换,因为会自动选择新证书:

{
  "AzureAd": {
    "ClientCredentials": [
      {
        "SourceType": "StoreWithDistinguishedName",
        "CertificateDistinguishedName": "CN=YourAppCertificate",
        "CertificateStorePath": "CurrentUser/My"
      }
    ]
  }
}

在 C# 中,使用帮助程序方法:

// By thumbprint
var credential = CredentialDescription.FromCertificateStore(
    "CurrentUser/My",
    thumbprint: "ABC123DEF456...");

// By distinguished name (recommended for rotation)
var credential = CredentialDescription.FromCertificateStore(
    "CurrentUser/My",
    distinguishedName: "CN=YourAppCertificate");

来自文件路径的证书

.pfx 磁盘上的文件加载证书:

{
  "AzureAd": {
    "ClientCredentials": [
      {
        "SourceType": "Path",
        "CertificateDiskPath": "/var/certs/app-cert.pfx",
        "CertificatePassword": "certificate-password"
      }
    ]
  }
}

警告

避免将证书密码直接存储在appsettings.json。 对敏感值使用 ASP.NET Core Secret Manager、环境变量或Azure 密钥保管库。

Base64 编码的证书

将证书直接作为 Base64 编码字符串嵌入配置中:

{
  "AzureAd": {
    "ClientCredentials": [
      {
        "SourceType": "Base64Encoded",
        "Base64EncodedValue": "MIIKcQIBAzCCCi0..."
      }
    ]
  }
}

客户端密码

指定用于开发和测试的客户端机密字符串:

{
  "AzureAd": {
    "ClientCredentials": [
      {
        "SourceType": "ClientSecret",
        "ClientSecret": "your-client-secret"
      }
    ]
  }
}

注意

客户端机密只能在开发期间使用。 切勿将机密提交到源代码管理或将其部署到生产环境。


将多个凭据与回退配合使用

可以在数组中 ClientCredentials 指定多个凭据。 Microsoft。Identity.Web 按顺序尝试每个凭据,如果当前凭据失败,则回退到下一个凭据。 此模式适用于在多个环境中运行的应用程序。

{
  "AzureAd": {
    "Instance": "https://login.microsoftonline.com/",
    "TenantId": "your-tenant-id",
    "ClientId": "your-client-id",
    "ClientCredentials": [
      {
        "SourceType": "SignedAssertionFromManagedIdentity",
        "ManagedIdentityClientId": "your-managed-identity-client-id"
      },
      {
        "SourceType": "KeyVault",
        "KeyVaultUrl": "https://your-keyvault.vault.azure.net",
        "KeyVaultCertificateName": "your-certificate-name"
      },
      {
        "SourceType": "ClientSecret",
        "ClientSecret": "development-only-secret"
      }
    ]
  }
}

在本示例中:

  1. 应用程序首先尝试使用托管标识进行无证书身份验证(适用于Azure)。
  2. 如果托管标识不可用,它将从密钥保管库降级到证书。
  3. 作为最后手段,它使用客户端密码(用于本地开发)。

此方法允许跨环境使用相同的配置文件,而无需更改代码。


在代码中配置凭据

你还可以在Program.csStartup.cs中以编程方式配置凭据。

using Microsoft.Identity.Web;

builder.Services.AddMicrosoftIdentityWebAppAuthentication(builder.Configuration, "AzureAd")
    .EnableTokenAcquisitionToCallDownstreamApi()
    .AddDownstreamApi("MyApi", builder.Configuration.GetSection("MyApi"))
    .AddDistributedTokenCaches();

// Or configure credentials programmatically
builder.Services.Configure<MicrosoftIdentityOptions>(options =>
{
    options.ClientCredentials = new[]
    {
        new CredentialDescription
        {
            SourceType = CredentialSource.SignedAssertionFromManagedIdentity,
            ManagedIdentityClientId = "your-managed-identity-client-id"
        }
    };
});

令牌解密凭据

除了用于身份验证的客户端凭据之外,Microsoft。Identity.Web 还支持用于令牌解密的凭据。 当应用程序收到加密令牌并需要解密令牌时,请使用令牌解密凭据。

令牌解密凭据使用与客户端凭据相同的 SourceType 值和配置模式,但在 TokenDecryptionCredentials 数组中指定。

{
  "AzureAd": {
    "TokenDecryptionCredentials": [
      {
        "SourceType": "KeyVault",
        "KeyVaultUrl": "https://your-keyvault.vault.azure.net",
        "KeyVaultCertificateName": "token-decryption-cert"
      }
    ]
  }
}

详细了解令牌解密


最佳做法

为应用程序配置凭据时,请记住以下建议:

在生产环境中优先使用无证书凭据。 它们消除了机密暴露风险并降低了轮换开销。 每当应用程序在支持托管标识的Azure计算资源上运行时,请使用它们。

使用凭据回退来增强可移植性。 按优先级顺序配置多个凭据,以便应用程序可在不更改代码的情况下跨开发、暂存和生产工作。

切勿在生产环境中使用客户端机密。 客户端机密可以通过日志、配置文件或源代码管理泄露。 请改用证书或无证书凭据。

将敏感值存储在配置文件之外。 将Azure 密钥保管库、环境变量或 ASP.NET Core机密管理器用于证书密码和客户端机密。 不要将敏感值提交到源代码管理。

在证书过期之前轮换证书。 监视证书过期日期并建立轮换过程。 Azure 密钥保管库可以自动续订证书。

将Azure 密钥保管库用于证书存储。 密钥保管库为证书提供集中管理、访问策略、审核日志记录和自动轮换。