ASP 에 대한 애플리케이션 기밀 정보를 저장하는 방법NET 핵심 프로젝트

주제 또는 개선에 대한 당신의 조언/Chris를 기꺼이 듣고 싶습니다.

This article is for you that is either completely new to ASP .NET Core or is currently storing your secrets in config files that you may or may not check in by mistake. Keep secrets separate, store them using the Secret management tool in dev mode, and look into services like Azure KeyVault for production.


응용 프로그램의 비밀과 설정, 그리고 왜 우리가 그것을 관리할 도구가 필요한지 이야기해 봅시다.다음과 같은 몇 가지 이유로 관리가 필요한 이유를 설명할 수 있습니다.

  • 구성/기밀을 소스 코드와 분리하여 구성에 민감하며, 구성 문자열에는 암호나 API 키 또는 기타 기밀이 포함될 수 있습니다.이 정보를 폭로하면 시스템이 공격을 받기 쉽다.원본 코드에 데이터를 저장하는 것을 피하고자 합니다. 원본 코드가 최종적으로 GitHub이나 비슷한 곳에서 재구매될 수 있기 때문입니다.개인 환매라도 노출될 수 있다.가장 좋은 것은 그것을 다른 곳에 보관하는 것이다.

  • 환경에 따라 값이 다르기 때문에 데이터베이스나 API에 연결할 때 개발, 등단과 제품 개발에 사용되는 값이 다를 수 있습니다.각 환경
  • 에서 교체해야 하는 구성으로 구분할 수 있도록 차이점을 이해해야 합니다.

  • OSS는 다르다. 모든 비밀을 환경 변수로 바꾸면 충분하다고 생각할 수도 있고, 완성할 수도 있다.그러나 너무 많은 설정이 있을 수 있습니다. 이 차원 구조로 구성해야 합니다. api:<apitype>:<apikey>단, : 는 모든 운영체제에서 지원되지 않지만, 다른 문자는 ___ 와 유사하다.관건은 당신의 비밀/배치를 조직하기 위해 추상적인 층이 필요하다는 것이다.

  • 도구책
  • Secret management
  • Configuration API
  • Sign up for a free Azure account
  • Deploy Web Api to Azure
  • Dependency Injection
  • Original post at Microsoft Tech Community blog

  • 비밀 관리 도구
    설치 시NET Core는 구성 및 기밀 관리를 위한 내장 도구를 제공합니다.그것은 우리가 지난 절에서 토론한 많은 문제를 해결했다.하지만 우리가 계속하기 전에 당신은 몇 가지 일을 알아야 합니다.

  • 이 도구는 로컬 개발자에게 매우 유용하고, 시크릿 관리자 도구는 로컬 개발에도 매우 유용하지만, 이것이 바로 이 도구가 보존해야 할 부분이다.

  • 환경 변수가 안전하지 않아서 기계가 해를 입을 수 있습니다. 환경 변수는 순수한 텍스트이고 암호화되지 않았습니다.따라서 환경 변수에 의존하여 Azure의 AppSetting에 저장하는 것은 유혹적이지만, 더욱 안전하게 기밀을 처리하는 방법을 찾고 싶습니다. 예를 들어 KeyVault.
  • secret manager 도구는 JSON 파일에 기밀을 저장하는 명령줄 도구입니다.특정 프로젝트를 초기화하면 도구가 Secrets Id를 생성하고 운영 체제에 의존하는 위치에 JSON 파일을 생성합니다.
    MAC에게
    ~/.microsoft/usersecrets/<user_secrets_id>/secrets.json
    
    창문.
    %APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json
    
    ASP의 루트 디렉토리에서 초기화하는 것이 좋습니다.NET 핵심 프로젝트, 프로젝트 파일에 Secrets Id를 배치합니다.그리고 그것은 할 수 있다.NET 핵심과 일부 제공 프로그램 코드는 코드를 통해 기밀을 검색하고 저장하는 것을 쉽게 한다.

    프레젠테이션 관리 기밀
    다음 사항을 살펴보겠습니다.

  • id를 생성하고 기밀을 포함하는 파일을 만드는 방법
  • 을 초기화합니다.

  • 터미널에서든 코드에서든 설정 값입니다.

  • 터미널과 코드 두 가지 측면에서 값을 찾을 수 있습니다.

  • 값을 삭제합니다. 더 이상 필요하지 않을 때, 값을 제거하는 방법을 아는 것이 좋습니다.터미널과 코드에서 삭제할 수 있습니다.

  • 초기화
  • 먼저 하나를 만듭니다.터미널에 다음 명령을 입력하여 NET 핵심 웹 API 프로젝트
  •    dotnet new webapi -o api --no-https
       cd api
    
  • 다음 명령을 입력합니다.
  •    dotnet user-secrets init
    
    터미널은 다음과 같은 출력을 제공해야 합니다.
       Set UserSecretsId to '<secret-id>' for MSBuild project '/path/to/your/project/project.csproj'.
    
  • 로 끝나는 프로젝트 파일을 엽니다.다음 그림과 같이 .csproj에서 항목을 찾습니다.
  •    <UserSecretsId>secret-id</UserSecretsId>
    
    이것PropertyGroup은 JSON 파일이 응용 프로그램에 어떻게 연결되는지 기밀 문서입니다.

    값 설정
    우리가 비밀을 만들기 전에, 우리가 현재 가지고 있는 비밀을 어떻게 열거하는지 배워라. (현재는 없을 것이다.)터미널에서 다음 명령을 입력합니다.
    dotnet user-secrets list
    
    다음과 같은 출력을 받아야 합니다.
    No secrets configured for this application.
    
    이제 비밀을 만들어 봅시다.
  • 터미널 유형:
  •    dotnet user-secrets set "ApiKey" "12345"
    
  • 비밀리에 저장된 컨텐츠 다시 표시:
  •    dotnet user-secrets list
    
    이제 다음과 같은 출력이 제공됩니다.
       ApiKey = 12345
    
    또한 컨텐트를 그룹화할 때 사용할 비밀이 포함된 네임스페이스를 만들 수도 있습니다. 예를 들어,
    ProductsUrl
    ProductsApiKey
    
  • 다음 명령을 입력하여 그룹 기밀을 만듭니다.
  •    dotnet user-secrets set "Products:Url" "http://path/to/product/url"
       dotnet user-secrets set "Products:ApiKey" "123abc"
    
    다음과 같은 출력을 받아야 합니다.
       Successfully saved Products:Url = http://path/to/product/url to the secret store.
       Successfully saved Products:ApiKey = 123abc to the secret store.
    
  • 당신의 비밀 내용을 열거합니다.
  •    Products:Url = http://path/to/product/url
       Products:ApiKey = 123abc
       ApiKey = 12345
    
    위의 내용은 스토리지UserSecretsId와 동일할 수 있지만 액세스할 때는 다릅니다.다음 방문을 시도해 봅시다.

    액세스 값ApiKey API는 소스 코드의 비밀을 검색하는 데 도움을 줍니다.이것은 강력한 API로 시작할 때 추가된 전용 제공 프로그램의 도움말 아래 Configuration, 환경 변수, KeyVault, 명령행 등 각종 원본에서 데이터를 읽을 수 있다.강조할 점은 이 API가 개발 모드에서만 기밀을 읽는 데 도움을 줄 수 있다는 점이다.비밀 관리 도구는 우리를 위해 일하기 위해 개발에만 사용된다.
  • 열기appsettings.json 및 구조 함수가 어떻게 이렇게 주입되는지 주의:
  •    public Startup(IConfiguration configuration) {}
    
  • 검색 Startup.cs 방법 및 다음 코드를 추가하여 기밀 정보를 검색하고 표시합니다.
  •    public void ConfigureServices(IServiceCollection services)
       {
          ApiKey = Configuration["Products:Url"];
          Console.WriteLine(ApiKey);
          services.AddControllers();
       }
    
  • 다음 명령을 실행하여 프로젝트를 구축하고 실행합니다.
  •    dotnet build && dotnet run
    
    맨 위에 다음과 같은 출력을 입력해야 합니다.
       http://path/to/product/url
    
    다행이다. 우리의 비밀이 이 열에 열거된 곳에 있다.만약 우리가 ConfigureServices() 이외의 다른 곳에서 이러한 값, 예를 들어 컨트롤러나 서비스에 접근하고 싶다면 어떻게 해야 합니까?그렇습니다. 내장된 의존 주입을 사용하면 우리는 이 점을 할 수 있습니다.

  • 우리는 그것을 사용해서 서비스나 컨트롤러에 주입할 수 있는 단례를 곧 등록할 것이다.singleton에는 액세스해야 할 API 키 또는 기타 기밀이 포함됩니다.
  • 파일Startup.cs을 생성하여 다음을 제공합니다.
  •   namespace webapi_secret
      {
        public class AppConfiguration
        {
          public string ApiKey { get; set; }
          public Product Product { get; set; }
        }
      }
    
  • 반환AppConfiguration.cs, Startup.cs 방법을 찾아 다음 줄을 추가합니다.
  •   var config = new AppConfiguration();
      config.ApiKey = Configuration["Products:Url"];
      services.AddSingleton<AppConfiguration>(config);
    
    이제 우리는 어느 곳에서든 사용할 수 있는 단례가 생겼다.
  • 생성 ConfigureServices():
  •   using Microsoft.AspNetCore.Mvc;
    
      namespace webapi_secret.Controllers
      {
        [ApiController]
        [Route("[controller]")]
        public class ProductsController : ControllerBase
        {
          AppConfiguration _config;
          public ProductsController(AppConfiguration config)
          {
            this._config = config;
          }
    
          [HttpGet]
          public string Get()
          {
            return this._config.ApiKey;
          }
        }
      }
    
    구조 함수에 ProductsController.cs를 주입하고 실례를 분배하는 방법AppConfiguration을 주의하십시오.또한 방법this._config = config;을 구성하고 구성 키를 반환하는 방법도 고려해야 합니다.
      [HttpGet]
      public string Get()
      {
        return this._config.ApiKey;
      }
    

  • 다음 명령을 사용하여 이 명령을 생성하고 실행합니다.
    dotnet build && dotnet run
    
  • 탐색 대상Get()
  • 이렇게 하고 필요한 경우 구성 인스턴스를 사용하거나 서비스를 만들고 구조 함수를 통해 전달되는 구성을 사용하여 DI 컨테이너에 등록할 수 있습니다.
  • 파일https://localhost:5001/products을 생성하여 다음을 제공합니다.
  •    namespace webapi_secret
        {
          public class HttpService
          {
            private string _apiKey;
            public HttpService(string apiKey)
            {
              this._apiKey = apiKey;
            }
    
            public string ApiKey { get { return _apiKey; } }
          }
        }
    
  • 파일HttpService.cs로 이동하여 Startup.cs 방법 및 다음 줄을 찾습니다.
  •    services.AddSingleton<HttpService>(new HttpService(Configuration["ApiKey"]));
    
    이제 필요한 곳에 주입 ConfigureService() 할 수 있고, API 키가 설정되어 있음을 알 수 있습니다.
    설정 실례를 주입하시겠습니까, 아니면 필요한 키로 서비스를 만드시겠습니까? 이것은 당신 자신에게 달려 있습니다.

    Wait, what those keys we created Products::ApiKey, all that talk of a namespace?


    네, 우리는 매우 우아한 방식으로 이 문제들을 처리할 수 있습니다.
  • 파일HttpService을 생성하여 다음을 제공합니다.
  •    public class ProductConfiguration
       {
         public string Url { get; set; }
         public string ApiKey { get; set; }
       }
    
  • 에서 ProductConfiguration.cs로 이동하여 다음 코드를 Startup.cs에 추가합니다.
  •    var productConfig = Configuration.GetSection("Products")
                              .Get<ProductConfiguration>();
       services.AddSingleton<ProductConfiguration>(productConfig);
    
    ConfigureServices() 방법은 이름 공간을 가져와 그 이름 공간의 모든 내용을 비추고 유형에 비추도록 합니다.좋습니다. 이제 기밀의 전용 부분을 전용 설정 클래스에 비출 수 있습니다.GetSection()처럼 우리는 마음대로 주사를 놓을 수 있다.AppConfiguration를 다음으로 업데이트합니다.
       using Microsoft.AspNetCore.Mvc;
    
        namespace webapi_secret.Controllers
        {
          [ApiController]
          [Route("[controller]")]
          public class ProductsController : ControllerBase 
          {
            AppConfiguration _config;
            ProductConfiguration _productConfig;
            public ProductsController(AppConfiguration config, ProductConfiguration productConfiguration)
            {
              this._config = config;
              this._productConfig = productConfiguration;
            }
    
            [HttpGet]
            public string Get()
            {
              // return this._config.ApiKey;
              return this._productConfig.ApiKey;
            }
          }
        }
    

    값 삭제
    마지막으로, 우리는 어떻게 정리합니까?명령ProductsController.cs을 사용하고 키 이름을 다음과 같이 지정합니다.
    dotnet user-secrets remove "ApiKey"
    
    또 하나의 remove 명령은 모든 키를 삭제할 수 있지만 주의해야 합니다.
    dotnet user-secret clear
    

    요약
    우리는 왜 원본 코드에 비밀을 숨기는 것이 나쁜 생각인지 토론했다. 즉, 당신이 그것을 잘못 서명할 수도 있다는 것이다.또한, 시크릿 관리자 도구가 개발 과정에서 귀하의 비밀을 추적하는 데 어떻게 도움을 줄 수 있는지 토론했습니다.그리고 우리는 비밀을 어떻게 관리하는지 보여주었다.
  • 기밀 추가
  • 명령줄 및 코드에서 기밀 읽기
  • DI 인스턴스를 기밀로 구성
  • 기밀 삭제
  • 나는 이것이 도움이 되기를 바란다.

    좋은 웹페이지 즐겨찾기