如何在.NET Core Startup配置中用MSI替换Azure AD凭据实现客户端认证
.NET Core中替换Azure AD凭据为MSI实现认证(结合密钥保管库证书指纹)
一、先完成Azure端配置
- 在你的Azure资源(如App Service、VM等)上启用MSI:
- 系统分配MSI:直接在资源的「标识」选项卡启用,自动生成专属标识。
- 用户分配MSI:先创建用户分配的MSI资源,再关联到目标业务资源。
- 给MSI分配密钥保管库权限:
进入密钥保管库的「访问策略」,添加新策略,选择你的MSI标识,授予「证书」权限组中的「获取」权限,保存策略。
二、修改配置文件(appsettings.json)
移除原有的Azure AD客户端凭据(ClientId、ClientSecret等敏感配置),添加密钥保管库和MSI相关配置:
{ "KeyVault": { "Url": "https://你的密钥保管库名称.vault.azure.net/", "CertificateFingerprint": "你的证书SHA-1/SHA-256指纹", "UserAssignedClientId": "用户分配MSI的ClientId" // 系统分配MSI可省略此项 }, "AzureAd": { "TenantId": "你的租户ID", "Issuer": "https://login.microsoftonline.com/你的租户ID/v2.0", "Audience": "你的API受众标识" } }
三、修改.NET Core代码实现MSI认证
1. 安装必要NuGet包
Install-Package Azure.Identity Install-Package Azure.Security.KeyVault.Certificates Install-Package Microsoft.AspNetCore.Authentication.JwtBearer
2. 配置密钥保管库客户端与认证服务(以.NET 6+ Program.cs为例)
var builder = WebApplication.CreateBuilder(args); // 初始化MSI凭据 var userAssignedClientId = builder.Configuration["KeyVault:UserAssignedClientId"]; TokenCredential credential = string.IsNullOrEmpty(userAssignedClientId) ? new DefaultAzureCredential() // 自动识别系统分配MSI或本地开发凭据(如Azure CLI、VS登录态) : new DefaultAzureCredential(new DefaultAzureCredentialOptions { ManagedIdentityClientId = userAssignedClientId }); // 从密钥保管库获取指定指纹的证书 var keyVaultUrl = builder.Configuration["KeyVault:Url"]; var certificateFingerprint = builder.Configuration["KeyVault:CertificateFingerprint"]; var certificateClient = new CertificateClient(new Uri(keyVaultUrl), credential); var certificateResponse = await certificateClient.GetCertificateAsync(certificateFingerprint); var certificate = certificateResponse.Value; // 配置JWT认证 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.Authority = $"https://login.microsoftonline.com/{builder.Configuration["AzureAd:TenantId"]}"; options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = true, ValidIssuer = builder.Configuration["AzureAd:Issuer"], ValidateAudience = true, ValidAudience = builder.Configuration["AzureAd:Audience"], // 使用从密钥保管库获取的证书验证令牌签名 IssuerSigningKey = new X509SecurityKey(certificate) }; // 若需用MSI调用下游服务,可在此扩展事件逻辑 options.Events = new JwtBearerEvents { OnTokenValidated = async context => { // 示例:获取调用下游API的访问令牌 var tokenClient = new TokenCredentialClient( new Uri($"https://login.microsoftonline.com/{builder.Configuration["AzureAd:TenantId"]}/oauth2/v2.0/token"), credential); var tokenResult = await tokenClient.GetTokenAsync( new TokenRequestContext(new[] { "https://下游API的范围/.default" })); context.HttpContext.Items["DownstreamApiAccessToken"] = tokenResult.Token; } }; }); builder.Services.AddAuthorization(); var app = builder.Build(); app.UseAuthentication(); app.UseAuthorization(); // 其他中间件与端点配置 app.Run();
关键说明
DefaultAzureCredential会自动适配运行环境:部署到Azure时使用MSI,本地开发时优先读取Azure CLI、Visual Studio等已登录的凭据,无需额外修改代码。- 确保证书指纹与密钥保管库中证书的指纹完全匹配(注意大小写,通常为SHA-1格式)。
- 若原代码中有用客户端凭据调用其他Azure服务的逻辑,直接替换为
DefaultAzureCredential即可,无需存储任何敏感凭据。
内容的提问来源于stack exchange,提问作者Siva
相关产品推荐
相关产品推荐

