已配置Azure MSI,如何在Node.js中获取令牌访问Key Vault?
嘿,我来帮你解决这个MSI获取访问令牌的问题!既然你已经配置好了Azure托管服务标识(MSI),并且环境变量里有MSI_ENDPOINT和MSI_SECRET,其实有两种方式可以获取令牌访问Key Vault,我推荐用官方SDK的方法,省心又可靠,当然也可以手动调用MSI端点,我都给你讲清楚。
推荐方法:使用Azure Identity SDK
这个SDK是微软官方维护的,已经封装了所有MSI相关的逻辑,不用自己手动处理请求细节,还能自动缓存令牌、处理重试,非常适合生产环境使用。
步骤1:安装依赖
首先安装必要的包:
npm install @azure/identity @azure/keyvault-secrets
如果只需要获取令牌,只装@azure/identity就行;如果要直接操作Key Vault,加上@azure/keyvault-secrets。
步骤2:编写代码获取令牌
下面是获取Key Vault访问令牌的TypeScript代码:
import { ManagedIdentityCredential } from "@azure/identity"; async function fetchAccessToken() { // 初始化MSI凭证实例 const msiCredential = new ManagedIdentityCredential(); // 请求Key Vault的权限范围,固定格式为https://vault.azure.net/.default const tokenResponse = await msiCredential.getToken("https://vault.azure.net/.default"); if (tokenResponse) { console.log("成功获取访问令牌:", tokenResponse.token); return tokenResponse.token; } else { throw new Error("未能获取到有效的访问令牌"); } } // 调用函数测试 fetchAccessToken().catch(error => console.error("出错了:", error));
直接访问Key Vault的示例
如果你想直接用MSI访问Key Vault的密钥,不用单独处理令牌,可以这样写:
import { ManagedIdentityCredential } from "@azure/identity"; import { SecretClient } from "@azure/keyvault-secrets"; async function retrieveSecret() { // 替换成你的Key Vault URL const vaultUrl = "https://your-key-vault-name.vault.azure.net"; const msiCredential = new ManagedIdentityCredential(); const secretClient = new SecretClient(vaultUrl, msiCredential); // 替换成你要获取的密钥名称 const secret = await secretClient.getSecret("your-target-secret-name"); console.log("获取到的密钥值:", secret.value); } retrieveSecret().catch(error => console.error("访问Key Vault失败:", error));
备选方法:手动调用MSI端点
如果你想了解底层实现,也可以直接用环境变量里的MSI_ENDPOINT和MSI_SECRET发送HTTP请求获取令牌,不过这种方法需要自己处理缓存、错误等,不推荐在生产环境使用:
步骤1:安装依赖
需要用到node-fetch来发送请求:
npm install node-fetch @types/node-fetch
步骤2:编写手动请求代码
import fetch from "node-fetch"; async function getTokenManually() { const msiEndpoint = process.env.MSI_ENDPOINT; const msiSecret = process.env.MSI_SECRET; if (!msiEndpoint || !msiSecret) { throw new Error("环境变量MSI_ENDPOINT或MSI_SECRET未正确配置"); } // 构造请求参数 const requestParams = new URLSearchParams({ resource: "https://vault.azure.net", api_version: "2017-09-01" }); const response = await fetch(`${msiEndpoint}?${requestParams}`, { method: "GET", headers: { "Secret": msiSecret } }); if (!response.ok) { throw new Error(`请求MSI端点失败: ${response.status} ${response.statusText}`); } const tokenData = await response.json(); console.log("手动获取的访问令牌:", tokenData.access_token); return tokenData.access_token; } getTokenManually().catch(error => console.error("手动获取令牌失败:", error));
最后提醒
不管用哪种方法,一定要确保你的MSI已经被授予Key Vault的相应权限(比如密钥的Get权限),否则即使拿到令牌也无法访问Key Vault资源。你可以在Azure门户的Key Vault访问策略里配置这个权限。
内容的提问来源于stack exchange,提问作者Bill Software Engineer
相关产品推荐
相关产品推荐

