자습서: 관리 ID를 사용하여 Key Vault를 .NET의 Azure 웹앱에 연결

Azure Key Vault는 보안이 강화된 자격 증명 및 기타 비밀을 저장하는 방법을 제공합니다. 그러나 코드는 Key Vault에 인증하여 이러한 항목을 검색해야 합니다. Azure 리소스에 대한 관리 ID를 통해 Microsoft Entra ID에서 자동으로 관리되는 ID를 Azure 서비스에 제공함으로써 이 문제를 해결할 수 있습니다. 이 ID를 사용하면 Key Vault를 비롯하여 Microsoft Entra 인증을 지원하는 모든 서비스에 인증할 수 있으므로 코드에 자격 증명을 표시할 필요가 없습니다.

이 자습서에서는 Azure 웹 애플리케이션을 만들고 Azure App Service에 배포합니다. 관리 ID를 사용하여 .NET용 Azure Key Vault 비밀 클라이언트 라이브러리Azure CLI를 통해 Azure Key Vault로 Azure 웹앱을 인증합니다. 선택한 개발 언어, Azure PowerShell 및/또는 Azure Portal을 사용하는 경우에도 동일한 기본 원칙이 적용됩니다.

이 자습서에서 제공하는 Azure App Service 웹 애플리케이션 및 배포에 대한 자세한 내용은 다음을 참조하세요.

필수 조건

이 자습서를 완전히 학습하려면 다음이 필요합니다.

Azure App Service에 배포된 웹 애플리케이션이 이미 있는 경우 키 자격 증명 모음에 대한 웹앱 액세스 구성웹 애플리케이션 코드 수정 섹션으로 건너뛸 수 있습니다.

.NET Core 앱 만들기

이 단계에서는 로컬 .NET Core 프로젝트를 설정합니다.

컴퓨터의 터미널 창에서 akvwebapp이라는 디렉터리를 만들고, 이를 현재 디렉터리로 만듭니다.

mkdir akvwebapp
cd akvwebapp

dotnet new web 명령을 사용하여 .NET Core 앱을 만듭니다.

dotnet new web

애플리케이션을 로컬로 실행하여 Azure에 이를 배포할 때 표시되는 모양을 확인합니다.

dotnet run

웹 브라우저에서 http://localhost:5000에 있는 앱으로 이동합니다.

페이지에 표시된 샘플 앱에서 "Hello World!" 메시지가 표시됩니다.

Azure용 웹 애플리케이션을 만드는 방법에 대한 자세한 내용은 Azure App Service에서 ASP.NET Core 웹앱 만들기를 참조하세요.

Azure에 앱 배포

이 단계에서는 로컬 Git을 사용하여 .NET Core 애플리케이션을 Azure App Service에 배포합니다. 애플리케이션을 만들고 배포하는 방법에 대한 자세한 내용은 Azure에서 ASP.NET Core 웹앱 만들기를 참조하세요.

로컬 Git 배포 구성

터미널 창에서 Ctrl+C를 선택하여 웹 서버를 닫습니다. .NET Core 프로젝트에 대한 Git 리포지토리를 초기화합니다.

git init --initial-branch=main
git add .
git commit -m "first commit"

FTP 및 로컬 Git에서 배포 사용자를 사용하여 Azure 웹앱을 배포할 수 있습니다. 배포 사용자가 구성되면 이를 모든 Azure 배포에 사용할 수 있습니다. 계정 수준 배포 사용자 이름 및 암호는 Azure 구독 자격 증명과 다릅니다.

배포 사용자를 구성하려면 az webapp deployment user set 명령을 실행합니다. 다음 지침을 준수하는 사용자 이름과 암호를 선택합니다.

  • 사용자 이름은 Azure 내에서 고유해야 합니다. 로컬 Git 푸시의 경우 at 기호(@)는 포함할 수 없습니다.
  • 암호는 8자 이상이어야 하며 문자, 숫자 및 기호의 세 가지 요소 중 두 가지를 포함해야 합니다.
az webapp deployment user set --user-name "<username>" --password "<password>"

JSON 출력에는 암호가 null로 나옵니다. 'Conflict'. Details: 409 오류가 발생하면 사용자 이름을 변경합니다. 'Bad Request'. Details: 400 오류가 발생하면 더 강력한 암호를 사용합니다.

웹앱을 배포하는 데 사용할 수 있도록 사용자 이름 및 암호를 기록해 둡니다.

리소스 그룹 만들기

리소스 그룹은 Azure 리소스를 배포하고 관리하는 논리적 컨테이너입니다. az group create 명령을 사용하여 키 자격 증명 모음과 웹앱을 모두 포함하는 리소스 그룹을 만듭니다.

az group create --name "myResourceGroup" -l "EastUS"

App Service 플랜 만들기

Azure CLI az appservice plan create 명령을 사용하여 App Service 요금제를 만듭니다. 다음 예에서는 FREE 가격 책정 계층에서 myAppServicePlan이라는 App Service 요금제를 만듭니다.

az appservice plan create --name myAppServicePlan --resource-group myResourceGroup --sku FREE

App Service 요금제가 만들어지면 Azure CLI에서 아래와 비슷한 정보를 표시합니다.

{ 
  "adminSiteName": null,
  "appServicePlanName": "myAppServicePlan",
  "geoRegion": "West Europe",
  "hostingEnvironmentProfile": null,
  "id": "/subscriptions/0000-0000/resourceGroups/myResourceGroup/providers/Microsoft.Web/serverfarms/myAppServicePlan",
  "kind": "app",
  "location": "West Europe",
  "maximumNumberOfWorkers": 1,
  "name": "myAppServicePlan",
  < JSON data removed for brevity. >
  "targetWorkerSizeId": 0,
  "type": "Microsoft.Web/serverfarms",
  "workerTierName": null
} 

자세한 내용은 Azure에서 App Service 계획 관리를 참조하세요.

웹앱 만들기

myAppServicePlan App Service 계획에서 Azure 웹앱을 만듭니다.

Important

키 자격 증명 모음과 마찬가지로 Azure 웹앱에는 고유한 이름이 있어야 합니다. 다음 예제에서 <your-webapp-name>을 웹앱의 이름으로 바꿉니다.

az webapp create --resource-group "myResourceGroup" --plan "myAppServicePlan" --name "<your-webapp-name>" --deployment-local-git

웹앱이 만들어지면 Azure CLI에서 아래와 비슷한 출력을 표시합니다.

Local git is configured with url of 'https://<username>@<your-webapp-name>.scm.azurewebsites.net/<ayour-webapp-name>.git'
{
  "availabilityState": "Normal",
  "clientAffinityEnabled": true,
  "clientCertEnabled": false,
  "clientCertExclusionPaths": null,
  "cloningInfo": null,
  "containerSize": 0,
  "dailyMemoryTimeQuota": 0,
  "defaultHostName": "<your-webapp-name>.azurewebsites.net",
  "deploymentLocalGitUrl": "https://<username>@<your-webapp-name>.scm.azurewebsites.net/<your-webapp-name>.git",
  "enabled": true,
  < JSON data removed for brevity. >
}

Git 원격의 URL은 deploymentLocalGitUrl 속성에서 https://<username>@<your-webapp-name>.scm.azurewebsites.net/<your-webapp-name>.git 형식으로 표시됩니다. 이 URL을 저장합니다. 나중에 필요합니다.

이제 main 분기에서 배포하도록 웹앱을 구성합니다.

 az webapp config appsettings set -g MyResourceGroup --name "<your-webapp-name>" --settings deployment_branch=main

다음 명령을 사용하여 새 앱으로 이동합니다. <your-webapp-name>을 앱 이름으로 바꿉니다.

https://<your-webapp-name>.azurewebsites.net

새 Azure 웹앱에 대한 기본 웹 페이지가 표시됩니다.

로컬 앱 배포

로컬 터미널 창으로 돌아와서 로컬 Git 리포지토리에 Azure 원격을 추가합니다. 다음 명령에서 <deploymentLocalGitUrl-from-create-step>웹앱 만들기 섹션에서 저장한 Git 원격의 URL로 바꿉니다.

git remote add azure <deploymentLocalGitUrl-from-create-step>

다음 명령을 사용하여 앱을 배포할 Azure 원격에 푸시합니다. Git 자격 증명 관리자에서 자격 증명을 요구하는 메시지가 표시되면 로컬 Git 배포 구성 섹션에서 만든 자격 증명을 사용합니다.

git push azure main

이 명령을 실행하는 데 몇 분 정도 걸릴 수 있습니다. 실행되는 동안 아래와 비슷한 정보가 표시됩니다.

Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 285 bytes | 95.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0), pack-reused 0
remote: Deploy Async
remote: Updating branch 'main'.
remote: Updating submodules.
remote: Preparing deployment for commit id 'd6b54472f7'.
remote: Repository path is /home/site/repository
remote: Running oryx build...
remote: Build orchestrated by Microsoft Oryx, https://github.com/Microsoft/Oryx
remote: You can report issues at https://github.com/Microsoft/Oryx/issues
remote:
remote: Oryx Version      : 0.2.20200114.13, Commit: 204922f30f8e8d41f5241b8c218425ef89106d1d, ReleaseTagName: 20200114.13
remote: Build Operation ID: |imoMY2y77/s=.40ca2a87_
remote: Repository Commit : d6b54472f7e8e9fd885ffafaa64522e74cf370e1
.
.
.
remote: Deployment successful.
remote: Deployment Logs : 'https://<your-webapp-name>.scm.azurewebsites.net/newui/jsonviewer?view_url=/api/deployments/d6b54472f7e8e9fd885ffafaa64522e74cf370e1/log'
To https://<your-webapp-name>.scm.azurewebsites.net:443/<your-webapp-name>.git
   d87e6ca..d6b5447  main -> main

웹 브라우저를 사용하여 배포된 애플리케이션으로 이동하거나 해당 애플리케이션을 새로 고칩니다.

http://<your-webapp-name>.azurewebsites.net

http://localhost:5000을 방문했을 때 이전에 확인한 "Hello World!" 메시지가 표시됩니다.

Git을 사용한 웹 애플리케이션 배포에 대한 자세한 내용은 Azure App Service에 로컬 Git 배포를 참조하세요.

웹앱을 구성하여 Key Vault에 연결

이 섹션에서는 Key Vault에 대한 웹 액세스를 구성하고, Key Vault에서 비밀을 검색하도록 애플리케이션 코드를 업데이트합니다.

관리 ID 만들기 및 할당

이 자습서에서는 관리 ID를 사용하여 Key Vault에 인증합니다. 관리 ID는 애플리케이션 자격 증명을 자동으로 관리합니다.

Azure CLI에서 애플리케이션에 대한 ID를 만들려면 az webapp-identity assign 명령을 실행합니다.

az webapp identity assign --name "<your-webapp-name>" --resource-group "myResourceGroup"

이 명령은 다음 JSON 코드 조각을 반환합니다.

{
  "principalId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "tenantId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "type": "SystemAssigned"
}

키 자격 증명 모음에서 getlist 작업을 수행할 수 있는 권한을 웹앱에 부여하려면 principalId를 Azure CLI az keyvault set-policy 명령에 전달합니다.

az keyvault set-policy --name "<your-keyvault-name>" --object-id "<principalId>" --secret-permissions get list

또한 Azure Portal 또는 PowerShell을 사용하여 액세스 정책을 할당할 수 있습니다.

키 자격 증명 모음에 액세스하도록 앱 수정

이 자습서에서는 Azure Key Vault 비밀 클라이언트 라이브러리를 데모용으로 사용합니다. 또한 Azure Key Vault 인증서 클라이언트 라이브러리 또는 Azure Key Vault 키 클라이언트 라이브러리를 사용할 수 있습니다.

패키지 설치

터미널 창에서 .NET용 Azure Key Vault 비밀 클라이언트 라이브러리 및 Azure ID 클라이언트 라이브러리 패키지를 설치합니다.

dotnet add package Azure.Identity
dotnet add package Azure.Security.KeyVault.Secrets

코드 업데이트

akvwebapp 프로젝트에서 .NET 5.0 이하용 Startup.cs 파일 또는 .NET 6.0용 Program.cs 파일을 찾아 엽니다.

다음 줄을 헤더에 추가합니다.

using Azure.Identity;
using Azure.Security.KeyVault.Secrets;
using Azure.Core;

다음 줄을 app.UseEndpoints 호출(.NET 5.0 이하) 또는 app.MapGet 호출(.NET 6.0) 앞에 추가하여 키 자격 증명 모음의 vaultUri를 반영하도록 URI를 업데이트합니다. 이 코드는 DefaultAzureCredential()을 사용하여 Key Vault에 인증하며, Key Vault는 관리 ID의 토큰을 사용하여 인증합니다. Key Vault에 인증하는 방법에 대한 자세한 내용은 개발자 가이드를 참조하세요. 또한 Key Vault가 제한되는 경우 이 코드는 지수 백오프를 다시 시도에 사용합니다. Key Vault 트랜잭션 제한에 대한 자세한 내용은 Azure Key Vault 제한 지침을 참조하세요.

SecretClientOptions options = new SecretClientOptions()
    {
        Retry =
        {
            Delay= TimeSpan.FromSeconds(2),
            MaxDelay = TimeSpan.FromSeconds(16),
            MaxRetries = 5,
            Mode = RetryMode.Exponential
         }
    };
var client = new SecretClient(new Uri("https://<your-unique-key-vault-name>.vault.azure.net/"), new DefaultAzureCredential(),options);

KeyVaultSecret secret = client.GetSecret("<mySecret>");

string secretValue = secret.Value;
.NET 5.0 이하

await context.Response.WriteAsync("Hello World!"); 줄을 다음 줄과 같이 업데이트합니다.

await context.Response.WriteAsync(secretValue);
.NET 6.0

app.MapGet("/", () => "Hello World!"); 줄을 다음 줄과 같이 업데이트합니다.

app.MapGet("/", () => secretValue);

다음 단계를 계속하기 전에 변경 내용을 저장해야 합니다.

웹앱 재배포

이제 코드가 업데이트되었으므로 다음 Git 명령을 사용하여 이를 Azure에 다시 배포할 수 있습니다.

git add .
git commit -m "Updated web app to access my key vault"
git push azure main

완성된 웹앱으로 이동

http://<your-webapp-name>.azurewebsites.net

이제 비밀 값이 이전에 "Hello World!"가 표시된 위치에 표시됩니다.

다음 단계