You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在非Azure托管Web API中用用户Azure访问令牌获取Key Vault密钥

问题:使用登录用户凭据访问Azure Key Vault而非服务主体

我正在开发一个采用Azure AD认证的网站,用户通过Azure AD凭据登录。当用户触发网站操作时,Angular前端调用.NET 6 Web API端点,并将Azure访问令牌传递给Web API。该端点随后调用Azure Key Vault获取密钥并执行其他操作。

目前我已通过ClientSecretCredential使用Azure服务主体实现Web API获取Key Vault密钥,代码如下:

var credential = new ClientSecretCredential(TenantId, ClientId, ClientSecret);
var client = new SecretClient(new Uri(VaultName), credential);
var success = await client.SetSecretAsync(secretName, value);

这段代码运行正常,但我希望改用登录用户的凭据而非服务主体账户来获取密钥。Web API仅能收到访问令牌,我尝试从该令牌构造Azure.Core.TokenCredential对象却未能成功——文档中所有继承自Azure.Core.TokenCredential的类均无对应构造方法。

Web前端与Web API均托管在Azure外部,恳请指点实现目标的方法。

相关TokenCredential派生类列表:

Azure.Identity.AuthorizationCodeCredential
Azure.Identity.AzureCliCredential
Azure.Identity.AzureDeveloperCliCredential
Azure.Identity.AzurePowerShellCredential
Azure.Identity.ChainedTokenCredential
Azure.Identity.ClientAssertionCredential
Azure.Identity.ClientCertificateCredential
Azure.Identity.ClientSecretCredential
Azure.Identity.DefaultAzureCredential
Azure.Identity.DeviceCodeCredential
Azure.Identity.EnvironmentCredential
Azure.Identity.InteractiveBrowserCredential
Azure.Identity.ManagedIdentityCredential
Azure.Identity.OnBehalfOfCredential
Azure.Identity.SharedTokenCacheCredential
Azure.Identity.UsernamePasswordCredential
Azure.Identity.VisualStudioCodeCredential
Azure.Identity.VisualStudioCredential
Azure.Identity.WorkloadIdentityCredential

解决方案:通过On-Behalf-Of流程实现用户身份委托

你需要使用OnBehalfOfCredential类来实现用户身份委托(OBO)流程,这正是为Web API接收用户令牌后,以用户身份调用下游服务(如Key Vault)的场景设计的。

步骤1:配置Azure AD应用权限

  • 为Web API的应用注册添加Key Vault的委托权限(如Key Vault Secrets User),并确保用户已同意该权限。
  • 为Web API应用注册配置自身的客户端凭据(Client Secret或Client Certificate),用于向Azure AD请求代表用户的令牌。
  • 前端请求用户令牌时,需包含Key Vault的作用域(如https://vault.azure.net/user_impersonation)。

步骤2:实现OnBehalfOfCredential代码

在Web API中,从请求头提取用户访问令牌,再用OnBehalfOfCredential构造凭据调用Key Vault:

// 从Authorization头提取用户访问令牌
var authHeader = Request.Headers.Authorization.ToString();
var userAccessToken = authHeader.Replace("Bearer ", string.Empty);

// 初始化OnBehalfOfCredential
var oboCredential = new OnBehalfOfCredential(
    tenantId: "你的Azure AD租户ID",
    clientId: "Web API的应用注册ID",
    clientSecret: "Web API的客户端密钥",
    userAssertionToken: userAccessToken);

// 创建SecretClient并执行操作
var secretClient = new SecretClient(new Uri("你的Key Vault URI"), oboCredential);
var secret = await secretClient.GetSecretAsync("目标密钥名称");

替代方案:自定义TokenCredential

如果不需要OBO流程(比如用户令牌已直接包含Key Vault访问权限),可以自定义一个TokenCredential实现,直接复用用户令牌:

public class UserTokenCredential : TokenCredential
{
    private readonly string _token;
    private readonly DateTimeOffset _expiresAt;

    public UserTokenCredential(string accessToken)
    {
        _token = accessToken;
        var jwtHandler = new JwtSecurityTokenHandler();
        var jwtToken = jwtHandler.ReadJwtToken(accessToken);
        _expiresAt = jwtToken.ValidTo;
    }

    public override ValueTask<AccessToken> GetTokenAsync(TokenRequestContext requestContext, CancellationToken cancellationToken)
    {
        return ValueTask.FromResult(new AccessToken(_token, _expiresAt));
    }

    public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)
    {
        return new AccessToken(_token, _expiresAt);
    }
}

使用示例:

var userCredential = new UserTokenCredential(userAccessToken);
var secretClient = new SecretClient(new Uri(VaultName), userCredential);
var success = await secretClient.SetSecretAsync(secretName, value);

内容的提问来源于stack exchange,提问作者Viet Nguyen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 16:52:43