msal-node通过SPN证书获取Azure AD令牌报错ERR_OSSL_PEM_NO_START_LINE
解决方案
ERR_OSSL_PEM_NO_START_LINE 错误是Node.js的OpenSSL模块无法识别传入的私钥格式导致的,你直接从Key Vault Secrets接口获取的证书内容是Base64编码的PFX二进制数据,不是msal-node要求的PEM格式明文私钥,因此解析失败。
解决步骤如下:
- 第一步:修改Key Vault返回数据的解析逻辑,解码PFX内容并提取PEM格式私钥,修改后的核心代码如下:
const crypto = require('crypto'); const msal = require('@azure/msal-node'); const { DefaultAzureCredential } = require('@azure/identity'); const { CertificateClient } = require('@azure/keyvault-certificates'); const { SecretClient } = require('@azure/keyvault-secrets'); const getazureToken = async () => { const credential = new DefaultAzureCredential(); const client = new CertificateClient(config.keyVaultUrl, credential); const secretClient = new SecretClient(config.keyVaultUrl, credential); const certResponse = await client.getCertificate(config.certificateName); // 指纹统一转大写,避免部分场景下小写校验失败 const thumbprint = certResponse.properties.x509Thumbprint.toString('hex').toUpperCase(); const secretResponse = await secretClient.getSecret(config.certificateName); // 解码Key Vault返回的Base64编码PFX内容 const pfxBuffer = Buffer.from(secretResponse.value, 'base64'); // 解析PFX提取私钥,第二个参数为PFX证书密码,无密码则传空字符串 const pfxParsed = crypto.pkcs12.parse(pfxBuffer, ''); let privateKeyPem = ''; // 遍历PFX内容找到私钥 for (const safeContent of pfxParsed.safeContents) { for (const bag of safeContent.safeBags) { if (bag.type === 'pkcs8ShroudedKeyBag' || bag.type === 'keyBag') { privateKeyPem = bag.key.export({ type: 'pkcs8', format: 'pem' }); break; } } if (privateKeyPem) break; } await msalApp(thumbprint, privateKeyPem); }; // 原有msalApp函数逻辑保持不变 async function msalApp(thumbprint, privateKey) { // 原有代码不变 }
- 第二步:本地验证证书有效性,你可以用手里的PFX文件直接替换Key Vault获取逻辑,先确认证书本身没有问题:
const fs = require('fs'); // 读取本地PFX文件 const pfxBuffer = fs.readFileSync('你的本地PFX文件路径.pfx'); // 后续解析PFX、提取私钥和指纹的逻辑和上述一致
- 第三步:校验配置参数正确性:确认客户端凭证流使用的scopes格式为
{资源标识}/.default,例如调用Azure管理接口的scope为https://management.azure.com/.default,同时确认你的服务主体已经被授予了对应资源的访问权限。 - 第四步:检查Key Vault访问权限:确认你的运行身份(DefaultAzureCredential对应的身份,本地开发为AZ CLI登录账号、部署环境为托管身份)已经在Key Vault的访问策略中被授予了证书获取和秘密获取权限。
如果你的Node.js版本低于v15,无法使用内置的crypto.pkcs12 API,可以引入第三方库node-forge完成PFX解析,解析逻辑和上述流程一致。
内容的提问来源于stack exchange,提问作者Avani Bataviya
相关产品推荐
相关产品推荐

