[英]azure active directory get access token using SPN with certificate in msal-node js facing error "ERR_OSSL_PEM_NO_START_LINE "
我正在尝试使用 msal 节点从 azure 获取访问令牌,并且需要遵循带有证书的服务原则。 目前我正在使用密钥保管库 url 来读取证书。 我的参考文档是https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/samples/msal-node-samples/auth-code-key-vault/index.js
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');
const secretResponse = await secretClient.getSecret(config.certificateName);
const privateKey = secretResponse.value;
await msalApp(thumbprint, privateKey);
};
async function msalApp(thumbprint, privateKey) {
// Before running the sample, you will need to replace the values in the config
const msalConfig = {
auth: {
clientId: config.azureClientId,
authority: `${config.authorityUri}${config.tenantId}/`,
clientCertificate: {
thumbprint,
privateKey,
},
},
system: {
loggerOptions: {
loggerCallback(loglevel, message, containsPii) {
console.log('loglevel', loglevel, message);
},
piiLoggingEnabled: false,
logLevel: msal.LogLevel.Verbose,
},
},
};
// Create msal application object
const cca = new msal.ConfidentialClientApplication(msalConfig);
const authCodeUrlParameters = {
scopes: config.scope,
};
cca
.acquireTokenByClientCredential(authCodeUrlParameters)
.then((response) => {
console.log('==========> response', response);
})
.catch((error) =>
console.log('error------------->', JSON.stringify(error))
);
}
我也有证书的 .pfx 文件。 如果有帮助的话。
解决方案是您可以使用以下代码从证书的 .pfx 文件中提取 .pem 文件
const forge = require('node-forge');
const fs = require('fs');
const convertPfxToPem = async (keyFile, passphrase) => {
const keyBase64 = keyFile.toString('base64');
const p12Der = forge.util.decode64(keyBase64);
const asn = forge.asn1.fromDer(p12Der);
const p12 = forge.pkcs12.pkcs12FromAsn1(asn, false, passphrase);
// Retrieve key data
const keyData = p12
.getBags({ bagType: forge.pki.oids.pkcs8ShroudedKeyBag })
[forge.pki.oids.pkcs8ShroudedKeyBag].concat(
p12.getBags({ bagType: forge.pki.oids.keyBag })[forge.pki.oids.keyBag]
);
// Convert a Forge private key to an ASN.1 RSAPrivateKey
const rsaPrivateKey = forge.pki.privateKeyToAsn1(keyData[0].key);
// Wrap an RSAPrivateKey ASN.1 object in a PKCS#8 ASN.1 PrivateKeyInfo
const privateKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPrivateKey);
// Convert a PKCS#8 ASN.1 PrivateKeyInfo to PEM
const privateKey = forge.pki.privateKeyInfoToPem(privateKeyInfo);
fs.writeFileSync('key.pem', privateKey);
return {
key: privateKey,
};
};
现在读取 .pfx 文件并存储 key.pem 并使用它。
let key = null;
if (fs.existsSync(path.resolve(__dirname, '../key.pem'))) {
key = fs.readFileSync(path.resolve(__dirname, '../key.pem'));
} else {
const pemResponse = await convertPfxToPem(
fs.readFileSync(path.resolve(__dirname, '../certificate.pfx')),
config.passphrase
);
key = pemResponse.key;
}
和 getazureToken 如下所示
const credential = new DefaultAzureCredential();
const client = new CertificateClient(config.keyVaultUrl, credential);
const certResponse = await client.getCertificate(config.certificateName);
const thumbprint = certResponse.properties.x509Thumbprint.toString('hex');
let key = null;
if (fs.existsSync(path.resolve(__dirname, '../key.pem'))) {
key = fs.readFileSync(path.resolve(__dirname, '../key.pem'));
} else {
const pemResponse = await convertPfxToPem(
fs.readFileSync(path.resolve(__dirname, '../certificate.pfx')),
config.passphrase
);
key = pemResponse.key;
}
try {
const tokenResponse = await msalApp(thumbprint, key);
return tokenResponse;
} catch (err) {}
当我们尝试以 pem 格式上传的证书格式不正确时,可能会发生此错误。
请在Pem.js文件中检查您的证书格式。 请确认pem文件的内容ie; 证书字符串和私钥字符串具有以下格式:这意味着用行包围密钥,包括 BEGIN / END CERTIFICATE 前后的 5 个连字符,每个连字符在不同的行中。 像下面这样
-----开始私钥-----\\nLONG_STRING_HERE\\n-----结束私钥-----
(检查是否遗漏了任何字符或连字符)您可以在此处检查您的证书,然后尝试删除(空格)ie; 在 BEGIN / END CERTIFICATE 之后和之前的“\\s”,并将它们替换为来自证书正则表达式和来自 pem.js 文件的私钥正则表达式的新行“\\n”,借助已经涉及的函数或相应地手动修改。
请检查https://github.com/auth0/node-jsonwebtoken/issues/642#issuecomment 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.