연습 - 관리 ID를 사용하여 .NET에서 사용자 지정 애플리케이션 구성

완료됨

Azure Key Vault에 애플리케이션 연결 문자열, 자격 증명, 암호 및 기타 중요한 정보를 저장할 수 있습니다. Key Vault에 액세스하려면 자격 증명을 제공해야 합니다. 이제 애플리케이션이 Azure VM으로 이동함에 따라 관리 ID를 사용하여 Key Vault에 인증할 액세스 토큰을 가져오도록 업데이트할 수 있습니다.

재고 추적 애플리케이션은 Azure SQL Database에 연결합니다. 이전에는 온-프레미스 앱이 구성 파일에 연결 문자열을 저장했습니다. Azure로 마이그레이션하는 과정의 일환으로 이제 모든 자격 증명 및 연결 문자열을 Azure Key Vault에 안전하게 저장합니다.

재고 추적 애플리케이션은 VM(가상 머신)에서 실행되므로 앞서 만든 시스템 할당 관리 ID를 사용할 수 있습니다. VM에 대한 적절한 권한을 부여하는 정책을 키 자격 증명 모음에 추가합니다.

이 연습에서는 새 키 자격 증명 모음을 사용하도록 앱을 편집합니다. 그런 다음, 앱이 데이터베이스 연결을 검색할 수 있도록 VM 액세스를 위한 관리 ID를 부여합니다. 마지막으로 Key Vault에 액세스하고 정보를 검색하기 위해 VM에서 앱을 빌드하고 실행합니다.

Key Vault에서 비밀 정보를 가져오는 앱 만들기

  1. 앞서 만든 VM에 로그인합니다.

    ssh $publicIP
    

    참고 항목

    환경 변수 publicIP 가 설정되지 않은 경우 다음 명령을 실행하여 다시 설정합니다.

    export publicIP=$(az vm show \
        --name prodserver \
        --resource-group <rgn>[Sandbox resource group]</rgn> \
        --show-details \
        --query [publicIps] \
        --output tsv)
    

    그런 후 ssh $publicIP 명령을 실행합니다.

  2. identity/secretapp 폴더로 이동합니다.

    cd ~/identity/secretapp
    
  3. nano 편집기를 사용하여 Program.cs 파일을 엽니다.

    nano Program.cs
    

    이 파일에는 샘플 앱의 C# 소스 코드가 들어 있습니다.

  4. Main 메서드를 검사합니다.

    static async Task Main(string[] args)
    {
        await GetSecretFromKeyVault().ConfigureAwait(false);
    }
    

    이 메서드는 GetSecretFromKeyVault 메서드를 호출하는 애플리케이션의 진입점입니다.

  5. GetSecretFromKeyVault 메서드가 나올 때까지 내려갑니다. 메서드의 첫 번째 코드 블록을 검사합니다.

    private static async Task GetSecretFromKeyVault()
    {
        var keyVaultName = "<key vault name>";
        Uri keyVaultUri = new Uri($"https://{keyVaultName}.vault.azure.net");
    
        SecretClient secretClient = new SecretClient(keyVaultUri, new DefaultAzureCredential());
        ...
    }
    

    "<key vault name>"를 키 자격 증명 모음 이름으로 바꿉니다. 이 코드는 DefaultAzureCredential을 사용하여 요청을 수행할 클라이언트를 인증합니다. 이 코드는 내부적으로 코드를 실행하는 VM에 대한 시스템 관리 ID를 얻습니다. 그런 다음 이 인증 체계를 활용할 SecretClient의 인스턴스를 생성합니다. 이 SecretClient 인스턴스를 사용하여 키 자격 증명 모음의 비밀에 액세스할 수 있습니다.

  6. 코드의 다음 부분을 확인합니다.

    var keyVaultSecretName = "<secret name>";
    
    try
    {
        var secret = await secretClient.GetSecretAsync(keyVaultSecretName).ConfigureAwait(false);
    
        Console.WriteLine($"Secret: {secret.Value}");
    }
    catch (Exception exp)
    {
        Console.WriteLine($"Something went wrong: {exp.Message}");
    }
    

    <secret name>를 키 자격 증명 모음에서 만든 암호의 이름인 "DBCredentials"로 바꿉니다.

    이 코드 블록은 SecretClientGetSecretAsync 메서드를 호출하여 특정 비밀을 검색하고 해당 값을 표시합니다. 클라이언트에 키 액세스 권한이 없는 경우 이 코드는 예외를 throw하고 오류 메시지를 표시합니다.

    참고

    코드에 저장되는 암호, 인증서 또는 클라이언트 암호는 없습니다.

  7. 변경 내용을 저장하려면 Ctrl+O를 누른 후 Enter 키를 누릅니다.

  8. nano 편집기를 닫으려면 Ctrl+X를 누릅니다.

애플리케이션 테스트

  1. 다음 명령을 실행하여 애플리케이션을 빌드합니다.

    dotnet restore
    dotnet build
    

    프로그램을 올바르게 편집했다면 애플리케이션이 오류 없이 빌드될 것입니다.

  2. 애플리케이션을 실행합니다.

    dotnet run
    

    VM의 서비스 사용자는 키 자격 증명 모음에 액세스할 수 있는 권한이 아직 부여되지 않았습니다. 그러므로 애플리케이션은 다음과 같은 오류 메시지로 응답해야 합니다.

    Something went wrong: Operation returned an invalid status code 'Forbidden'

서비스 사용자가 Key Vault에서 비밀을 검색할 수 있도록 권한을 부여합니다.

  1. VM에 대한 연결을 닫습니다.

    exit
    
  2. 이전 연습에서 VM의 보안 주체 ID를 기록했습니다. 보안 주체 ID를 기억하지 못하는 경우 다음 명령을 실행하여 VM의 시스템 할당 ID를 찾습니다. ($VMNAME 변수는 이전 연습에서 prodserver의 값으로 설정되었습니다.)

    az vm identity show \
      --name $VMNAME \
      --resource-group <rgn>[Sandbox resource group]</rgn>
    

    다음 코드는 반환된 값의 예입니다. ID는 다릅니다.

    {
        "principalId": "aba6da53-9180-47fc-8fc4-4b35f154e845",
        "tenantId": "a95baa51-dcb1-4b9a-8312-8774a8afddbe",
        "type": "SystemAssigned",
        "userAssignedIdentities": null
    }
    

    이 값을 사용하여 다음 명령에서 보안 주체 ID만 반환합니다.

  3. 이 보안 주체 ID를 사용하여 VM에 Key Vault에서 비밀을 검색하고 나열할 수 있는 권한을 부여합니다.

    az keyvault set-policy \
        --name $KVNAME \
        --secret-permissions get list \
        --object-id $(az vm identity show \
                        --name $VMNAME \
                        --resource-group <rgn>[Sandbox resource group]</rgn> \
                        --output tsv \
                        --query principalId)
    

    반환된 값은 JSON 형식입니다. 여기에는 ID, 위치, 이름 및 연결된 모든 속성이 포함됩니다.

애플리케이션을 다시 테스트

  1. VM에 로그인합니다.

    ssh $publicIP
    
  2. identity/secretapp 폴더로 변경합니다.

    cd ~/identity/secretapp
    
  3. 애플리케이션을 실행합니다.

    dotnet run
    

    이번에는 애플리케이션이 Key Vault에서 비밀을 검색하고 해당 값을 표시할 것입니다.

    Database connection string:: Server=tcp:prodserverSQL.database.windows.net,1433;Database=myDataBase;User ID=mylogin@myserver;Password=examplePassword;Trusted_Connection=False;Encrypt=True;