Azure Key Vault 연동: .NET Core에서 Microsoft.Azure.KeyVault 라이브러리로 비밀 정보 읽기

지난 글에서는 Azure Key Vault가 실제 프로젝트에서 어떻게 활용되는지 살펴봤습니다. Azure Key Vault는 키 관리 서비스로, 암호화 키를 손쉽게 생성 및 제어하고 인증서와 비밀 정보를 관리할 수 있게 해줍니다. 개발자 입장에서는 애플리케이션 코드에 이러한 비밀 정보를 포함할 필요가 없어집니다. Azure Key Vault의 URL만 설정하고, 적절한 인증 권한을 부여하면 애플리케이션이 키 자격 증명 모음에 접근할 수 있습니다.

이번 글에서는 .NET Core 웹 프로젝트에 Microsoft.Azure.KeyVault 패키지를 추가하고 비밀 정보를 가져오는 방법을 중점적으로 다룹니다. 현재 이 NuGet 패키지는 대체되었지만, 여전히 사용 가능합니다.

NuGet 주소: https://www.nuget.org/packages/Microsoft.Azure.KeyVault/3.0.5

1. Azure Key Vault에 비밀 정보(Secret) 생성

Azure Portal에 로그인하여 미리 생성된 Key Vault에 비밀 정보를 추가합니다.

  • 이름: Blog, 값: cnbate-blog
  • 이름: Count, 값: 10
  • 이름: Timestamp, 값: 2022-02-19 23:17

Azure CLI나 포털에서 직접 값을 입력할 수 있습니다.

2. 환경 변수 및 액세스 권한 설정

Azure에 등록한 서비스 주체의 AZURE_CLIENT_ID(애플리케이션 ID), AZURE_CLIENT_SECRET(클라이언트 암호), AZURE_TENANT_ID(테넌트 ID)를 시스템 환경 변수나 Visual Studio 실행 환경에 설정해야 합니다. 본 예제에서는 시스템 환경 변수를 사용합니다.

자세한 내용은 이전 글인 ".NET Core 콘솔 앱에서 Key Vault 비밀 정보 가져오기"를 참고하세요.

3. 프로젝트에 NuGet 패키지 설치

.NET Core 웹 프로젝트를 새로 만들고, 다음 패키지를 설치합니다.

  • Microsoft.Azure.KeyVault (버전 3.0.5)
  • Microsoft.Extensions.Configuration.AzureKeyVault (버전 3.1.22)
  • Azure.Extensions.AspNetCore.Configuration.Secrets (버전 1.2.1)
  • Azure.Identity (버전 1.5.0)

패키지 관리자 콘솔에서 다음 명령어를 실행합니다.

Install-Package Microsoft.Azure.KeyVault -Version 3.0.5
Install-Package Microsoft.Extensions.Configuration.AzureKeyVault -Version 3.1.22
Install-Package Azure.Extensions.AspNetCore.Configuration.Secrets -Version 1.2.1
Install-Package Azure.Identity -Version 1.5.0

4. 애플리케이션에서 Key Vault 연결 설정

애플리케이션이 Key Vault에 연결되면 별도의 구성 소스로 추가됩니다. 이후 다른 구성 데이터처럼 값을 읽을 수 있습니다.

IKeyVaultService 인터페이스

public interface IKeyVaultService
{
    Task<string> GetSecretByKeyAsync(string keyName);
}

KeyVaultService 클래스

public class KeyVaultService : IKeyVaultService
{
    private readonly IConfiguration _config;

    public KeyVaultService(IConfiguration config)
    {
        _config = config;
    }

    public Task<string> GetSecretByKeyAsync(string keyName)
    {
        return Task.FromResult(_config[keyName]);
    }
}

Program.cs - 호스트 빌더 확장 메서드 추가

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ApplyKeyVaultSetup()
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder
                .UseUrls("http://*:9004")
                .UseStartup<Startup>();
        });

ConfigureSetup.cs - 확장 메서드 구현

public static IHostBuilder ApplyKeyVaultSetup(this IHostBuilder host)
{
    if (host == null) throw new ArgumentNullException(nameof(host));

    return host.ConfigureAppConfiguration((context, config) =>
    {
        var env = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
        var jsonPath = $"appsettings.{env}.json";

        var settings = config.SetBasePath(context.HostingEnvironment.ContentRootPath)
            .AddJsonFile(jsonPath, optional: false, reloadOnChange: true)
            .Build();

        var credential = new DefaultAzureCredential();
        config.AddAzureKeyVault(
            new Uri(settings["AzureKeyVault:Endpoint"]),
            credential);
    });
}

appsettings.json - Key Vault 엔드포인트 설정

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AzureKeyVault": {
    "Endpoint": "https://cnbateblogweb-kv.vault.azure.net/"
  }
}

Startup.cs - 의존성 주입 등록

public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IKeyVaultService, KeyVaultService>();
    services.AddControllersWithViews();
}

5. 컨트롤러 및 뷰에서 비밀 정보 표시

HomeController

public class HomeController : Controller
{
    private readonly ILogger<HomeController> _logger;
    private readonly IKeyVaultService _vaultService;

    public HomeController(ILogger<HomeController> logger, IKeyVaultService vaultService)
    {
        _logger = logger;
        _vaultService = vaultService;
    }

    public async Task<IActionResult> Index()
    {
        var items = new List<KeyValueViewModel>
        {
            new() { Key = "Blog", Value = await _vaultService.GetSecretByKeyAsync("Blog") },
            new() { Key = "Count", Value = await _vaultService.GetSecretByKeyAsync("Count") },
            new() { Key = "Timestamp", Value = await _vaultService.GetSecretByKeyAsync("Timestamp") }
        };
        return View(items);
    }
}

Index.cshtml

@{
    ViewData["Title"] = "Home Page";
}
@model List<KeyValueViewModel>

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
    <h2>Azure Key Vault Secrets</h2>
    @foreach (var item in Model)
    {
        <p>Key: @item.Key | Value: @item.Value</p>
    }
</div>

프로젝트를 실행하면 브라우저에 Key Vault에서 가져온 비밀 정보 값이 표시됩니다.

이번 글에서는 .NET Core 웹 애플리케이션에서 Microsoft.Azure.KeyVault 라이브러리를 사용하여 Azure Key Vault에 저장된 비밀 정보를 중앙에서 관리하고 가져오는 방법을 알아보았습니다. Key Vault를 구성 소스로 추가하면 여러 애플리케이션에서 동일한 설정을 공유할 수 있으며, App Service에서도 활용 가능합니다. 연결 설정이 완료되면 일반 구성 데이터를 읽는 방식과 동일하게 Key Vault 값을 사용할 수 있습니다.

태그: Azure Key Vault .NET Core Microsoft.Azure.KeyVault 비밀 정보 관리 DefaultAzureCredential

7월 17일 18:04에 게시됨