-1

我正在尝试使用 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 证书文件。如果有帮助的话。

4

2 回答 2

0

解决方案是您可以使用以下代码从证书的 .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) {}
于 2021-10-19T14:07:26.567 回答
-1

当我们尝试以 pem 格式上传的证书格式不正确时,可能会出现此错误。

请检查Pem.js文件中的证书格式。请确认pem文件的内容是否为ie;证书字符串和私钥字符串具有以下格式:这意味着用行包围密钥,包括在 BEGIN / END CERTIFICATE 之前和之后的 5 个连字符,每个连字符在不同的行中。像下面的东西

-----开始私钥-----\nLONG_STRING_HERE\n-----结束私钥-----

(检查是否遗漏了任何字符或连字符)您可以在此处检查您的证书 然后尝试删除(空格)ie;“\s” 在 BEGIN / END CERTIFICATE 之后和之前,并借助已涉及的功能或手动修改相应的证书正则表达式和 pem.js 文件中的私钥正则表达式中的新行“\n”替换它们。

请也检查https://github.com/auth0/node-jsonwebtoken/issues/642#issuecomment

于 2021-10-18T09:42:04.807 回答