다음을 통해 공유


Node.js 웹앱에서 인증을 위해 클라이언트 인증서 사용

적용: 회색 X 기호가 있는 흰색 원. 인력 테넌트 흰색 확인 표시 기호가 있는 녹색 원입니다. 외부 테넌트(자세히 알아보기)

Microsoft Entra 외부 ID는 기밀 클라이언트 애플리케이션에 두 가지 유형의 인증인 암호 기반 인증(예: 클라이언트 암호) 및 인증서 기반 인증을 지원합니다. 더 높은 수준의 보안을 위해 기밀 클라이언트 애플리케이션에서 자격 증명으로 클라이언트 암호 대신 인증서를 사용하는 것이 좋습니다.

프로덕션에서는 잘 알려진 인증 기관에서 서명한 인증서를 구입하고 Azure Key Vault를 사용하여 인증서 액세스 및 수명을 관리해야 합니다. 그러나 테스트 목적으로 자체 서명된 인증서를 만들고 이를 통해 인증하도록 앱을 구성할 수 있습니다.

이 문서에서는 Azure Portal, OpenSSL 또는 PowerShell에서 Azure Key Vault를 사용하여 자체 서명된 인증서를 생성하는 방법을 알아봅니다. 클라이언트 암호가 이미 있는 경우 이를 안전하게 삭제하는 방법을 알아봅니다.

필요한 경우 .NET, Node.js, Go, Python 또는 Java 클라이언트 라이브러리를 사용하여 프로그래밍 방식으로 자체 서명된 인증서를 만들 수도 있습니다.

필수 조건

자체 서명된 인증서 만들기

로컬 컴퓨터에 기존 자체 서명된 인증서가 있는 경우 이 단계를 건너뛴 다음 앱 등록에 인증서 업로드를 진행합니다.

Azure Key Vault를 사용하여 앱에 대한 자체 서명된 인증서를 생성할 수 있습니다. Azure Key Vault를 사용하면 파트너 CA(인증 기관) 할당 및 인증서 회전 자동화와 같은 이점을 활용할 수 있습니다.

Azure Key Vault에 기존 자체 서명된 인증서가 있고 이를 다운로드하지 않고 사용하려면 이 단계를 건너뛰고 Azure Key Vault에서 직접 자체 서명된 인증서 사용을 진행합니다. 그렇지 않은 경우 다음 단계에서 인증서를 생성합니다.

  1. Azure Portal을 사용하여 Azure Key Vault에서 인증서 설정 및 검색의 단계에 따라 인증서를 만들고 다운로드합니다.

  2. 인증서를 만든 후 .cer 파일과 .pfx 파일(예: ciam-client-app-cert.cerciam-client-app-cert.pfx)을 모두 다운로드합니다. .cer 파일에는 공개 키가 포함되어 있으며 Microsoft Entra 관리 센터에 업로드하는 파일입니다.

  3. 터미널에서 다음 명령을 실행하여 .pfx 파일에서 프라이빗 키를 추출합니다. 암호를 입력하라는 메시지가 표시될 때 암호를 설정하지 않으려면 Enter 키를 누르기만 하면 됩니다. 그렇지 않으면 원하는 암호를 입력합니다.

    openssl pkcs12 -in ciam-client-app-cert.pfx -nocerts -out ciam-client-app-cert.key
    

    ciam-client-app-cert.key 파일은 앱에서 사용하는 파일입니다.

앱 등록에 인증서 업로드

클라이언트 앱 인증서를 사용하려면 Microsoft Entra 관리 센터에 등록한 앱을 인증서와 연결해야 합니다.

  1. 최소한 응용 프로그램 관리자Microsoft Entra 관리 센터에 로그인합니다.

  2. 여러 테넌트에 액세스할 수 있는 경우 상단 메뉴의 설정 아이콘 을 사용하여 디렉터리 + 구독 메뉴에서 외부 테넌트로 전환합니다.

  3. ID>애플리케이션>앱 등록으로 이동합니다.

  4. 앱 등록 목록에서 ciam-client-app과 같이 인증서와 연결하려는 앱을 선택합니다.

  5. 관리에서 인증서 및 비밀을 선택합니다.

  6. 인증서를 선택한 다음 인증서 업로드를 선택합니다.

  7. 파일 선택 파일 아이콘을 선택한 다음 업로드할 인증서(예: ciam-client-app-cert.pem, ciam-client-app-cert.cer 또는 ciam-client-app-cert.crt)를 선택합니다.

  8. 설명CIAM 클라이언트 앱 인증서와 같은 설명을 입력한 다음 추가를 선택하여 인증서를 업로드합니다. 인증서가 업로드되면 지문, 시작 날짜만료 값이 표시됩니다.

  9. 나중에 클라이언트 앱을 구성할 때 사용할 수 있도록 지문 값을 기록해 두세요.

애플리케이션에 대해 이미 클라이언트 암호가 있는 경우 악성 애플리케이션이 애플리케이션을 가장하는 것을 방지하려면 이를 삭제해야 합니다.

  1. 클라이언트 암호 탭으로 이동하여 삭제 아이콘을 선택합니다.
  2. 나타나는 팝업 창에서 를 선택합니다.

인증서를 사용하도록 Node.js 앱 구성

앱 등록을 인증서와 연결한 후에는 인증서 사용을 시작하려면 앱 코드를 업데이트해야 합니다.

  1. authConfig.jsmsalConfig와 같은 MSAL 구성 개체가 포함된 파일을 찾은 후 다음 코드와 비슷하게 보이도록 업데이트합니다. 클라이언트 암호가 있는 경우 이를 제거해야 합니다.

    require('dotenv').config();
    const fs = require('fs'); //// import the fs module for reading the key file
    const crypto = require('crypto');
    const TENANT_SUBDOMAIN = process.env.TENANT_SUBDOMAIN || 'Enter_the_Tenant_Subdomain_Here';
    const REDIRECT_URI = process.env.REDIRECT_URI || 'http://localhost:3000/auth/redirect';
    const POST_LOGOUT_REDIRECT_URI = process.env.POST_LOGOUT_REDIRECT_URI || 'http://localhost:3000';
    
    const privateKeySource = fs.readFileSync('PATH_TO_YOUR_PRIVATE_KEY_FILE')
    
    const privateKeyObject = crypto.createPrivateKey({
        key: privateKeySource,
        passphrase: 'Add_Passphrase_Here',
        format: 'pem'
    });
    
    const privateKey = privateKeyObject.export({
        format: 'pem',
        type: 'pkcs8'
    });
    
    /**
     * Configuration object to be passed to MSAL instance on creation.
     * For a full list of MSAL Node configuration parameters, visit:
     * https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/dev/lib/msal-node/docs/configuration.md
     */
        const msalConfig = {
            auth: {
                clientId: process.env.CLIENT_ID || 'Enter_the_Application_Id_Here', // 'Application (client) ID' of app registration in Azure portal - this value is a GUID
                authority: process.env.AUTHORITY || `https://${TENANT_SUBDOMAIN}.ciamlogin.com/`, 
                clientCertificate: {
                    thumbprint: "YOUR_CERT_THUMBPRINT", // replace with thumbprint obtained during step 2 above
                    privateKey: privateKey
                }
            },
            //... Rest of code in the msalConfig object
        };
    
    module.exports = {
        msalConfig,
        REDIRECT_URI,
        POST_LOGOUT_REDIRECT_URI,
        TENANT_SUBDOMAIN
    };
    

    코드에서 자리 표시자를 바꿉니다.

    • Add_Passphrase_Here를 프라이빗 키를 암호화하는 데 사용한 암호로 바꿉니다.

    • YOUR_CERT_THUMBPRINT를 이전에 기록한 지문 값으로 바꿉니다.

    • PATH_TO_YOUR_PRIVATE_KEY_FILE을 프라이빗 키 파일의 파일 경로로 바꿉니다.

    • Enter_the_Application_Id_Here를 이전에 등록한 앱의 애플리케이션(클라이언트) ID로 바꿉니다.

    • Enter_the_Tenant_Subdomain_Here를 디렉터리(테넌트) 하위 도메인으로 바꿉니다. 예를 들어, 테넌트 기본 도메인이 contoso.onmicrosoft.com인 경우 contoso를 사용합니다. 테넌트 이름이 없는 경우 테넌트 세부 정보를 읽는 방법을 알아봅니다.

    키를 암호화했으므로(암호화하는 것이 좋음) MSAL 구성 개체에 전달하기 전에 암호를 해독해야 합니다.

    //...
    const privateKeyObject = crypto.createPrivateKey({
        key: privateKeySource,
        passphrase: 'Add_Passphrase_Here',
        format: 'pem'
    });
    
    const privateKey = privateKeyObject.export({
        format: 'pem',
        type: 'pkcs8'
    });
    //...
    
  2. 앱을 테스트하려면 웹앱 실행 및 테스트의 단계를 따릅니다.

Azure Key Vault에서 직접 자체 서명된 인증서 사용

Azure Key Vault에서 직접 기존 인증서를 사용할 수 있습니다.

  1. authConfig.jsmsalConfig와 같은 MSAL 구성 개체가 포함된 파일을 찾은 다음 clientSecret 속성을 제거합니다.

    const msalConfig = {
        auth: {
            clientId: process.env.CLIENT_ID || 'Enter_the_Application_Id_Here', // 'Application (client) ID' of app registration in Azure portal - this value is a GUID
            authority: process.env.AUTHORITY || `https://${TENANT_SUBDOMAIN}.ciamlogin.com/`, 
        },
        //...
    };
    
  2. Azure CLI를 설치한 후 콘솔에 다음 명령을 입력하여 로그인합니다.

    az login --tenant YOUR_TENANT_ID
    

    자리 표시자 YOUR_TENANT_ID를 이전에 복사한 디렉터리(테넌트) ID로 바꿉니다.

  3. 콘솔에서 다음 명령을 입력하여 필수 패키지를 설치합니다.

    npm install --save @azure/identity @azure/keyvault-certificates @azure/keyvault-secrets
    
  4. 클라이언트 앱에서 다음 코드를 사용하여 thumbprintprivateKey를 생성합니다.

    const identity = require("@azure/identity");
    const keyvaultCert = require("@azure/keyvault-certificates");
    const keyvaultSecret = require('@azure/keyvault-secrets');
    
    const KV_URL = process.env["KEY_VAULT_URL"] || "ENTER_YOUR_KEY_VAULT_URL"
    const CERTIFICATE_NAME = process.env["CERTIFICATE_NAME"] || "ENTER_THE_NAME_OF_YOUR_CERTIFICATE_ON_KEY_VAULT";
    
    // Initialize Azure SDKs
    const credential = new identity.DefaultAzureCredential();
    const certClient = new keyvaultCert.CertificateClient(KV_URL, credential);
    const secretClient = new keyvaultSecret.SecretClient(KV_URL, credential);
    
    async function getKeyAndThumbprint() {
    
        // Grab the certificate thumbprint
        const certResponse = await certClient.getCertificate(CERTIFICATE_NAME).catch(err => console.log(err));
        const thumbprint = certResponse.properties.x509Thumbprint.toString('hex')
    
        // When you upload a certificate to Key Vault, a secret containing your private key is automatically created
        const secretResponse = await secretClient.getSecret(CERTIFICATE_NAME).catch(err => console.log(err));;
    
        // secretResponse contains both public and private key, but we only need the private key
        const privateKey = secretResponse.value.split('-----BEGIN CERTIFICATE-----\n')[0]
    }
    
    getKeyAndThumbprint();        
    

    코드에서 자리 표시자를 바꿉니다.

    • ENTER_YOUR_KEY_VAULT_URL을 Azure Key Vault URL로 바꿉니다.

    • ENTER_THE_NAME_OF_YOUR_CERTIFICATE_ON_KEY_VAULT를 Azure Key Vault에 있는 인증서 이름으로 바꿉니다.

  5. 구성을 업데이트하려면 thumbprintprivateKey 값을 사용합니다.

    let clientCert = {
        thumbprint: thumbprint, 
        privateKey: privateKey,
    };
    
    msalConfig.auth.clientCertificate = clientCert; //For this to work, you can't declares your msalConfig using const modifier 
    
  6. 그런 다음 getMsalInstance 메서드에 표시된 대로 기밀 클라이언트 인스턴스화를 진행합니다.

    class AuthProvider {
        //...
        getMsalInstance(msalConfig) {
            return new msal.ConfidentialClientApplication(msalConfig);
        }
        //...
    }
    
  7. 앱을 테스트하려면 웹앱 실행 및 테스트의 단계를 따릅니다.

다음 단계

다음의 방법을 알아보세요.