Použití přihlašovacích údajů certifikátu s uzlem MSAL

Důvěrné klientské aplikace můžete vytvářet pomocí MSAL Node (webové aplikace, aplikace démona atd.). Přihlašovací údaje klienta jsou pro důvěrné klienty povinné.

Předpoklady

Důvěrné klientské aplikace můžete vytvářet pomocí MSAL Node (webové aplikace, aplikace démona atd.). Přihlašovací údaje klienta jsou pro důvěrné klienty povinné. Přihlašovací údaje klienta můžou být:

  • managed identity: Jedná se o scénář bez certifikátů, kdy je vztah důvěryhodnosti vytvořený prostřednictvím infrastruktury Azure. Nevyžaduje se žádná správa tajných kódů nebo certifikátů. MSAL zatím tuto funkci nepodporuje, ale místo něj můžete použít Azure Identity SDK. Viz dokumentaci ke spravovaným identitám pro prostředky Azure
  • clientSecret: Tajný řetězec vygenerovaný během registrace aplikace nebo aktualizovaný po registraci stávající aplikace. To se nedoporučuje pro produkční prostředí.
  • clientCertificate: Certifikát nastavený během registrace aplikace. Certifikát musí mít privátní klíč, protože se používá k podepisování kontrolního výrazu , který vygeneruje knihovna MSAL. Jedná se thumbprintSha256 o kryptografický otisk SHA-256 X.509 certifikátu a privateKey jedná se o privátní klíč kódovaný PEM.
  • clientAssertion: Místo toho, aby služba MSAL vytvořila kontrolní výraz, převezme vývojář aplikace kontrolu. Užitečné pro přidání dalších claimů ke kontrolnímu tvrzení nebo pro použití služby Key Vault k podepisování namísto místního certifikátu. Certifikát použitý k podepsání kontrolního výrazu je stále potřeba nastavit během registrace aplikace.

Poznámka: U aplikací 1P může být také vyžadováno odesílání x5c. Toto je řetěz certifikátů X.509 používaný v scénářích ověřování podle názvu subjektu nebo vystavitele.

Bezpečné používání tajných kódů a certifikátů

Tajné kódy by nikdy neměly být pevně zakódované. Balíček dotenv npm lze použít k ukládání tajných kódů nebo certifikátů do souboru .env (umístěného v kořenovém adresáři projektu), který by měl být součástí souboru .gitignore, aby se zabránilo náhodnému nahrání tajných kódů.

Certifikáty lze také číst ze souborů prostřednictvím modulu fs nodeJS. Nikdy by ale neměly být uložené v adresáři projektu. Produkční aplikace by měly načítat certifikáty z Azure služby KeyVault nebo jiných zabezpečených trezorů klíčů.

Další informace najdete v certifikátech a tajných kódech .

Projděte si ukázku MSAL: auth-code-with-certs

Registrace certifikátů

Pokud certifikát nemáte, můžete vytvořit certifikát podepsaný svým držitelem pomocí PowerShellu nebo pomocí Azure služby KeyVault.

Certifikát musíte nahrát do Microsoft Entra ID.

  1. Přejděte na portál Azure a vyberte registraci Microsoft Entra aplikace.
  2. Vlevo vyberte okno Certifikáty a tajné kódy .
  3. Klikněte na Nahrát certifikát a vyberte soubor certifikátu, který chcete nahrát (např. example.crt).
  4. Klikněte na tlačítko Přidat. Po nahrání certifikátu se zobrazí kryptografický otisk (SHA-256),počáteční datum a hodnoty vypršení platnosti .

Další informace najdete v tématu: Registrace certifikátu v Microsoft identity platform

Inicializace uzlu MSAL pomocí certifikátů

const msal = require('@azure/msal-node');
require('dotenv').config(); // process.env now has the values defined in a .env file

const config = {
    auth: {
        clientId: "YOUR_CLIENT_ID",
        authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
        clientCertificate: {
            thumbprintSha256: process.env.thumbprint,
            privateKey: process.env.privateKey,
        }
    }
};

// Create msal application object
const cca = new msal.ConfidentialClientApplication(config);

U obou thumbprintSha256 a privateKey se očekává, že budou řetězce. privateKey se dále očekává, že bude v následujícím formátu (PKCS#8):

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIJQwIBADANBgkqhkiG9w0BAQEFAASCCS0wggkpAgEAAoICAQDkpKPrsfpIijS3
z2HCpDsa7dxOsKIrm7F1AtGBjyB0yVDjlh/FA7jT5sd2ypBh3FVsZGJudQsLRKfE
// ...
-----END ENCRYPTED PRIVATE KEY-----

Note

Případně může váš privátní klíč začínat -----BEGIN PRIVATE KEY----- (nešifrovaný PKCS#8) nebo -----BEGIN RSA PRIVATE KEY----- (PKCS#1). Tyto formáty jsou také přípustné. Následující kód lze použít k převodu libovolného kompatibilního klíče na typ klíče PKCS#8:

openssl pkcs8 -topk8 -inform PEM -outform PEM -in example.key -out example.key

Pokud jste zašifrovali privátní klíč (nebo pokud je privátní klíč už šifrovaný) pomocí předávací fráze, budete ho muset před předáním do uzlu MSAL dešifrovat.

Důležité: Nikdy nezakódujte hesla ve zdrojovém kódu. Privátní klíč certifikátu i volitelné heslo descryptionu by se měly načíst ze zabezpečeného umístění (např. Azure KeyVault) a bezpečně nasadit s webovým rozhraním API.

Můžete to provést pomocí kryptografického modulu Node. Použijte metodu createPrivateKey() k analýze a exportu klíče:

const fs = require('fs');
const crypto = require('crypto');

const privateKeySource = fs.readFileSync('<path_to_key>/example.key')

const privateKeyObject = crypto.createPrivateKey({
    key: privateKeySource,
    passphrase: process.env.YOUR_PASSPHRASE,
    format: 'pem'
});

const privateKey = privateKeyObject.export({
    format: 'pem',
    type: 'pkcs8'
});

(Volitelné) Převod pfx na pem

OpenSSL lze použít k převodu souborů certifikátů kódovaných pfx na pem:

    openssl pkcs12 -in certificate.pfx -out certificate.pem

Pokud se převod musí provést programově, možná budete muset spoléhat na balíček třetí strany, protože Node.js pro to nenabízí žádnou nativní metodu. Můžete například použít oblíbenou implementaci protokolu TLS, jako je například node-forge, provést:

const forge = require('node-forge');

/**
 * @param {string} pfx: certificate + private key combination in pfx format
 * @param {string} passphrase: passphrase used to encrypt pfx file
 * @returns {Object}
 */
function convertPFX(pfx, passphrase = null) {

    const asn = forge.asn1.fromDer(forge.util.decode64(pfx));
    const p12 = forge.pkcs12.pkcs12FromAsn1(asn, true, 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]);

    // Retrieve certificate data
    const certBags = p12.getBags({ bagType: forge.pki.oids.certBag })[forge.pki.oids.certBag];
    const certificate = forge.pki.certificateToPem(certBags[0].cert)

    // 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);

    console.log("Converted certificate: \n", certificate);
    console.log("Converted key: \n", privateKey);

    return {
        certificate: certificate,
        key: privateKey
    };
}

(Volitelné) Vytvoření serveru HTTPS

Protokol OAuth 2.0 doporučuje používat připojení HTTPS, kdykoli je to možné. Většina cloudových služeb, jako je Azure App Service, ve výchozím nastavení poskytuje připojení HTTPS přes proxy server. Pokud chcete pro účely testování nastavit vlastní server HTTPS, přečtěte si dokumentaci k Node.js s pokyny k vytvoření serveru HTTPS.

Abyste mohli obejít zásady zabezpečení prohlížeče, budete také muset přidat certifikáty podepsané svým držitelem dořetězu klíčů správce / přihlašovacích údajůvašeho operačního systému. V prohlížeči se pak může zobrazit upozornění (např. Chrome).

Warning

Možná budete potřebovat oprávnění správce ke spuštění výše uvedených příkazů.

Běžné problémy

V některých případech se vám může při pokusu o ověření identity pomocí certifikátů zobrazit chyba z Microsoft Entra ID, například chyba AADSTS700027: Client assertion contains an invalid signature, která značí, že certifikáty a/nebo soukromé klíče, které používáte k inicializaci MSAL Node, mají nesprávný formát. Běžným důvodem je to, že řetězec certifikátu nebo privátního klíče, který dodáváte do uzlu MSAL, obsahuje neočekávané znaky, jako jsou návratové znaky () nebo \r (\n):

-----BEGIN CERTIFICATE-----\nMIIDDzCCAfegAwIBAgIJAMkyzQVK88NHMA0GCSqGSIb3DQEBBQUAMIGCMQswCQYDVQQGEwJTRTESMBAGA1UECBMJU3RvY2tob2xtMQ4wDAYDVQQHEwVLaXN0YTEQMA4G0fbkqbKulrchGbNgkankZtEVg4PGjobZq7B+njvcVa7SsWF/WLq5AUbw==\r\n-----END CERTIFICATE-----

Případně může soubor certifikátu nebo klíče obsahovat bag attributes:

Bag Attributes
    localKeyID: 28 B5 8E 16 11 88 E9 00 58 D5 76 30 12 B9 59 B8 E4 CE 7C AA
subject=/C=UK/ST=Suffolk/L=Ipswich/O=Example plc/CN=alice
issuer=/C=UK/ST=Suffolk/L=Ipswich/O=Example plc/CN=Certificate Authority/emailAddress=ca@example.com\n
-----BEGIN CERTIFICATE-----
MIIDDzCCAfegAwIBAgIJAMkyzQVK88NHMA0GCSqGSIb3DQEBBQUAMIGCMQswCQYD
VQQGEwJTRTESMBAGA1UECBMJU3RvY2tob2xtMQ4wDAYDVQQHEwVLaXN0YTEQMA4G
0fbkqbKulrchGbNgkankZtEVg4PGjo+Y8MdMjtfSZB29hwYvfMX09jzJ68ZqmpYQ
njvcVtLbEZN5OGCkaslb/f2OxLbsUNgIbws538WnaaufDvKmQe2kUdWmpl9Wn9Bf
bZq7B+njvcVa7SsWF/WLq5AUbw==
-----END CERTIFICATE-----

V takových případech jste zodpovědní za vyčištění řetězce předtím, než jej předáte konfiguraci MSAL Node. Například:

const msal = require('@azure/msal-node');
const fs = require('fs');

const privateKeySource = fs.readFileSync('<path_to_key>/certs/example.key');
const privateKey = Buffer.from(privateKeySource, 'base64').toString().replace(/\r/g, "").replace(/\n/g, "");

const config = {
    auth: {
        clientId: "YOUR_CLIENT_ID",
        authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
        clientCertificate: {
            thumbprintSha256: process.env.thumbprint,
            privateKey: privateKey,
        }
    }
};

// Create msal application object
const cca = new msal.ConfidentialClientApplication(config);

Viz také