如何在.NET中编程创建Azure AD Service Principals并配置Key Vault证书凭据?
.NET中通过Service Principal创建Azure AD服务主体(含Key Vault证书凭据)
前置准备
- 安装所需NuGet包:
Install-Package Microsoft.Graph Install-Package Azure.Identity Install-Package Azure.Security.KeyVault.Certificates Install-Package Azure.Security.KeyVault.Secrets - 确保用于执行操作的Service Principal拥有以下Microsoft Graph应用权限(需管理员同意):
Application.ReadWrite.All
- 配置Azure Key Vault访问策略,给该Service Principal分配:
- 证书权限:
Get - 密钥/机密权限:
Get
- 证书权限:
完整代码示例
using Microsoft.Graph; using Microsoft.Graph.Models; using Microsoft.Graph.Models.ODataErrors; using Azure.Identity; using Azure.Security.KeyVault.Certificates; using Azure.Security.KeyVault.Secrets; using System.Security.Cryptography.X509Certificates; // 配置参数 var tenantId = "你的租户ID"; var clientId = "用于认证的Service Principal客户端ID"; var clientSecret = "用于认证的Service Principal客户端密钥"; // 也可替换为证书认证方式 var keyVaultUri = new Uri("https://你的KeyVault名称.vault.azure.net/"); var certificateName = "KeyVault中存储的证书名称"; var newAppDisplayName = "新创建的应用注册名称"; try { // 1. 认证到Microsoft Graph var graphClient = new GraphServiceClient( new ClientSecretCredential( tenantId, clientId, clientSecret, new ClientSecretCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud })); // 2. 从Key Vault获取证书及公钥信息 var certClient = new CertificateClient(keyVaultUri, new ClientSecretCredential(tenantId, clientId, clientSecret)); var cert = await certClient.GetCertificateAsync(certificateName); // 从Key Vault机密中获取完整证书链以提取公钥 var secretClient = new SecretClient(keyVaultUri, new ClientSecretCredential(tenantId, clientId, clientSecret)); var secret = await secretClient.GetSecretAsync(cert.Name, cert.Properties.Version); var x509Cert = new X509Certificate2(Convert.FromBase64String(secret.Value.Value)); // 提取公钥字节数组用于Graph API配置 var publicKeyBytes = x509Cert.GetPublicKey(); // 3. 创建应用注册(对应Service Principal会自动生成) var newApp = new Application { DisplayName = newAppDisplayName, Description = "通过Microsoft Graph创建的应用注册", KeyCredentials = new List<KeyCredential> { new KeyCredential { Type = "AsymmetricX509Cert", Usage = "Verify", Key = publicKeyBytes, DisplayName = certificateName, StartDateTime = DateTimeOffset.UtcNow, EndDateTime = x509Cert.NotAfter } } }; var createdApp = await graphClient.Applications.PostAsync(newApp); Console.WriteLine($"已创建应用注册,ID:{createdApp.Id}"); // 4. 验证并获取自动生成的Service Principal var servicePrincipal = await graphClient.ServicePrincipals .GetAsync((requestConfiguration) => { requestConfiguration.QueryParameters.Filter = $"appId eq '{createdApp.AppId}'"; }); if (servicePrincipal.Value.Any()) { Console.WriteLine($"对应的Service Principal已创建,ID:{servicePrincipal.Value.First().Id}"); } } catch (ODataError odataError) { Console.WriteLine($"Graph API错误:{odataError.Error.Message}"); } catch (Exception ex) { Console.WriteLine($"操作失败:{ex.Message}"); }
关键说明
- 代码中使用
ClientSecretCredential认证,可替换为ClientCertificateCredential实现调用方Service Principal的证书认证 - 从Key Vault获取证书时,需通过机密客户端获取完整证书链,才能提取Graph API所需的公钥信息
- 创建应用注册时,
KeyCredentials中仅需配置公钥,用于新Service Principal的身份验证 - 应用注册创建完成后,Azure AD会自动生成对应的Service Principal,无需单独调用创建接口
内容的提问来源于stack exchange,提问作者silent
相关产品推荐
相关产品推荐

