如何让使用DeviceCodeCredential的CLI应用以应用身份访问Azure资源?
问题分析与解决方案
你的问题核心在于:DeviceCodeCredential 是用户身份认证流程,获取的是当前登录个人账号的访问令牌,因此访问Key Vault时会用你的个人身份,而非应用注册的服务主体身份。哪怕给应用配置了权限,只要用的是用户令牌,就不会触发应用身份的权限校验。
要实现“用户通过DeviceCode登录验证身份,但用应用服务主体身份访问Key Vault”的需求,你需要使用Azure AD 的 On-Behalf-Of (OBO) 流程,这是唯一能在用户认证后,切换到应用身份访问资源的方式(且无需分发应用密钥)。
具体实现步骤(Java)
配置应用注册的OBO权限
- 登录Azure门户,找到你的应用注册,进入“API权限”页面。
- 添加Key Vault的委派权限:搜索“Azure Key Vault”,勾选“user_impersonation”权限,然后点击“授予管理员同意”。
- 确保应用注册已被添加为Key Vault的“Key Vault Secrets User”角色。
代码中实现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("你的密钥名称"); } }关键说明
- OBO流程中,用户登录后会生成一个用户令牌,应用将此令牌发送给Azure AD,请求获取以应用身份访问Key Vault的令牌。
- 此时Key Vault会校验应用服务主体的权限(即你配置的“Key Vault Secrets User”角色),而非用户个人的权限。
- 无需分发应用密钥,所有认证流程都通过用户交互式登录完成,符合内部CLI的安全需求。
内容的提问来源于stack exchange,提问作者Felix ZY
相关产品推荐
相关产品推荐

