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

如何让使用DeviceCodeCredential的CLI应用以应用身份访问Azure资源?

问题分析与解决方案

你的问题核心在于:DeviceCodeCredential 是用户身份认证流程,获取的是当前登录个人账号的访问令牌,因此访问Key Vault时会用你的个人身份,而非应用注册的服务主体身份。哪怕给应用配置了权限,只要用的是用户令牌,就不会触发应用身份的权限校验。

要实现“用户通过DeviceCode登录验证身份,但用应用服务主体身份访问Key Vault”的需求,你需要使用Azure AD 的 On-Behalf-Of (OBO) 流程,这是唯一能在用户认证后,切换到应用身份访问资源的方式(且无需分发应用密钥)。

具体实现步骤(Java)

  1. 配置应用注册的OBO权限

    • 登录Azure门户,找到你的应用注册,进入“API权限”页面。
    • 添加Key Vault的委派权限:搜索“Azure Key Vault”,勾选“user_impersonation”权限,然后点击“授予管理员同意”。
    • 确保应用注册已被添加为Key Vault的“Key Vault Secrets User”角色。
  2. 代码中实现OBO流程
    先通过DeviceCodeCredential获取用户的身份令牌,再以此令牌为断言创建OnBehalfOfCredential,最后用这个凭证访问Key Vault:

    import com.azure.identity.DeviceCodeCredential;
    import com.azure.identity.DeviceCodeCredentialBuilder;
    import com.azure.identity.OnBehalfOfCredential;
    import com.azure.identity.OnBehalfOfCredentialBuilder;
    import com.azure.security.keyvault.secrets.SecretClient;
    import com.azure.security.keyvault.secrets.SecretClientBuilder;
    import com.azure.core.credential.AccessToken;
    import java.util.concurrent.TimeUnit;
    
    public class KeyVaultOboExample {
        public static void main(String[] args) {
            // 1. 用DeviceCode获取用户令牌
            String clientId = "你的应用注册Client ID";
            String tenantId = "你的租户ID";
            DeviceCodeCredential deviceCodeCredential = new DeviceCodeCredentialBuilder()
                .clientId(clientId)
                .tenantId(tenantId)
                .challengeConsumer(challenge -> System.out.println(challenge.getMessage()))
                .build();
    
            // 获取用户的访问令牌(目标资源为应用自身的Client ID,用于OBO流程)
            AccessToken userToken = deviceCodeCredential.getToken(
                new com.azure.core.credential.TokenRequestContext()
                    .addScopes("api://" + clientId + "/.default")
            ).block();
    
            // 2. 用用户令牌创建OnBehalfOfCredential,获取应用身份的令牌
            OnBehalfOfCredential oboCredential = new OnBehalfOfCredentialBuilder()
                .clientId(clientId)
                .tenantId(tenantId)
                .userAssertion(userToken.getToken())
                .build();
    
            // 3. 用OBO凭证创建SecretClient访问Key Vault
            SecretClient secretClient = new SecretClientBuilder()
                .vaultUrl("https://你的密钥保管库名称.vault.azure.net/")
                .credential(oboCredential)
                .buildClient();
    
            // 示例:获取密钥
            secretClient.getSecret("你的密钥名称");
        }
    }
    
  3. 关键说明

    • OBO流程中,用户登录后会生成一个用户令牌,应用将此令牌发送给Azure AD,请求获取以应用身份访问Key Vault的令牌。
    • 此时Key Vault会校验应用服务主体的权限(即你配置的“Key Vault Secrets User”角色),而非用户个人的权限。
    • 无需分发应用密钥,所有认证流程都通过用户交互式登录完成,符合内部CLI的安全需求。

内容的提问来源于stack exchange,提问作者Felix ZY

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 07:52:47