当应用程序使用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"
}
]
}
}
在本示例中:
- 应用程序首先尝试使用托管标识进行无证书身份验证(适用于Azure)。
- 如果托管标识不可用,它将从密钥保管库降级到证书。
- 作为最后手段,它使用客户端密码(用于本地开发)。
此方法允许跨环境使用相同的配置文件,而无需更改代码。
在代码中配置凭据
你还可以在Program.cs或Startup.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 密钥保管库用于证书存储。 密钥保管库为证书提供集中管理、访问策略、审核日志记录和自动轮换。