ASP.NET Core에 대한 소비자 API 개요
IDataProtectionProvider
및 IDataProtector
인터페이스는 소비자가 데이터 보호 시스템을 사용하는 기본 인터페이스입니다. Microsoft.AspNetCore.DataProtection.Abstractions 패키지에 있습니다.
IDataProtectionProvider
공급자 인터페이스는 데이터 보호 시스템의 루트를 나타냅니다. 데이터를 보호하거나 보호 해제하는 데는 직접 사용할 수 없습니다. 대신 소비자는 IDataProtectionProvider.CreateProtector(purpose)
를 호출하여 IDataProtector
에 대한 참조를 받아야 합니다. 여기서 용도는 의도한 소비자 사용 사례를 설명하는 문자열입니다. 이 매개 변수의 의도 및 적절한 값을 선택하는 방법에 대한 자세한 내용은 용도 문자열을 참조하세요.
IDataProtector
보호기 인터페이스는 CreateProtector
에 대한 호출에 의해 반환되며, 소비자가 보호 및 보호 해제 작업을 수행하는 데 사용할 수 있는 이 인터페이스입니다.
데이터 조각을 보호하려면 Protect
메서드에 데이터를 전달합니다. 기본 인터페이스에서는 바이트[] -> 바이트[]로 변환하는 메서드를 정의하지만, 스트링 -> 스트링으로 변환하는 오버로드(확장 메서드로서 제공)도 있습니다. 두 메서드에서 제공하는 보안은 동일합니다. 개발자는 사용 사례에 가장 편리한 오버로드를 선택해야 합니다. 선택한 오버로드에 관계없이 Protect 메서드에서 반환된 값은 이제 보호되고(암호화 및 변조 방지) 애플리케이션에서 신뢰할 수 없는 클라이언트로 보낼 수 있습니다.
이전에 보호된 데이터 조각을 보호 해제하려면 보호된 데이터를 Unprotect
메서드에 전달합니다. (개발자 편의를 위해 바이트[] 기반 및 문자열 기반 오버로드가 있습니다.) 이 동일한 IDataProtector
에 대한 이전 Protect
호출에 의해 보호된 페이로드가 생성된 경우 Unprotect
메서드는 원래 보호되지 않은 페이로드를 반환합니다. 보호된 페이로드가 변조되었거나 다른 IDataProtector
에 의해 생성된 경우 Unprotect
메서드는 CryptographicException을 throw합니다.
동일한 개념과 다른 개념 IDataProtector
는 용도의 개념과 다시 연결합니다. 두 IDataProtector
인스턴스가 동일한 루트IDataProtectionProvider
에서 생성되었지만 IDataProtectionProvider.CreateProtector
에 대한 호출에서 다른 용도 문자열을 통해 생성된 경우 다른 보호기로 간주되며 다른 인스턴스에서 생성된 페이로드를 보호 해제할 수 없습니다.
이러한 인터페이스 사용
DI 인식 구성 요소의 경우 용도는 구성 요소가 해당 생성자에서 IDataProtectionProvider
매개 변수를 사용하며 구성 요소가 인스턴스화될 때 DI 시스템에서 이 서비스를 자동으로 제공하는 것입니다.
참고 항목
일부 애플리케이션(예: 콘솔 애플리케이션 또는 ASP.NET 4.x 애플리케이션)은 DI를 인식하지 못할 수 있으므로 여기에 설명된 메커니즘을 사용할 수 없습니다. 이러한 시나리오의 경우 DI를 거치지 않고 IDataProtection
공급자 인스턴스를 얻는 데 대한 자세한 내용은 비 DI 인식 시나리오 문서를 참조하세요.
다음 샘플에서는 세 가지 개념을 보여 줍니다.
서비스 컨테이너에 데이터 보호 시스템 추가
DI를 사용하여
IDataProtectionProvider
의 인스턴스 받기 및IDataProtectionProvider
에서IDataProtector
를 만들고 이를 사용하여 데이터를 보호 및 보호 해제
콘솔 앱
using System;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main(string[] args)
{
// add data protection services
var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection();
var services = serviceCollection.BuildServiceProvider();
// create an instance of MyClass using the service provider
var instance = ActivatorUtilities.CreateInstance<MyClass>(services);
instance.RunSample();
}
public class MyClass
{
IDataProtector _protector;
// the 'provider' parameter is provided by DI
public MyClass(IDataProtectionProvider provider)
{
_protector = provider.CreateProtector("Contoso.MyClass.v1");
}
public void RunSample()
{
Console.Write("Enter input: ");
string input = Console.ReadLine();
// protect the payload
string protectedPayload = _protector.Protect(input);
Console.WriteLine($"Protect returned: {protectedPayload}");
// unprotect the payload
string unprotectedPayload = _protector.Unprotect(protectedPayload);
Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
}
}
}
/*
* SAMPLE OUTPUT
*
* Enter input: Hello world!
* Protect returned: CfDJ8ICcgQwZZhlAlTZT...OdfH66i1PnGmpCR5e441xQ
* Unprotect returned: Hello world!
*/
웹 앱
Program.cs
에서 AddDataProtection(IServiceCollection, Action<DataProtectionOptions>)을 호출합니다.
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllersWithViews();
builder.Services.AddDataProtection();
var app = builder.Build();
다음 강조 표시된 코드는 컨트롤러에서 사용하는 IDataProtector 방법을 보여줍니다.
public class HomeController : Controller
{
private readonly IDataProtector _dataProtector;
public HomeController(IDataProtectionProvider dataProtectionProvider)
{
_dataProtector = dataProtectionProvider.CreateProtector("HomeControllerPurpose");
}
// ...
public IActionResult Privacy()
{
// The original data to protect
string originalData = "original data";
// Protect the data (encrypt)
string protectedData = _dataProtector.Protect(originalData);
Console.WriteLine($"Protected Data: {protectedData}");
// Unprotect the data (decrypt)
string unprotectedData = _dataProtector.Unprotect(protectedData);
Console.WriteLine($"Unprotected Data: {unprotectedData}");
return View();
}
// ...
패키지 Microsoft.AspNetCore.DataProtection.Abstractions
에는 개발자 편의를 위해 확장 메서드 GetDataProtector 가 포함되어 있습니다. 서비스 공급자에서 IDataProtectionProvider를 검색하고 IDataProtectionProvider.CreateProtector
를 호출하는 단일 작업으로 캡슐화됩니다. 다음 샘플에서는 사용량을 보여 줍니다.
using System;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.Extensions.DependencyInjection;
public class Program
{
public static void Main(string[] args)
{
// add data protection services
var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection();
var services = serviceCollection.BuildServiceProvider();
// get an IDataProtector from the IServiceProvider
var protector = services.GetDataProtector("Contoso.Example.v2");
Console.Write("Enter input: ");
string input = Console.ReadLine();
// protect the payload
string protectedPayload = protector.Protect(input);
Console.WriteLine($"Protect returned: {protectedPayload}");
// unprotect the payload
string unprotectedPayload = protector.Unprotect(protectedPayload);
Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
}
}
팁
IDataProtectionProvider
및 IDataProtector
의 인스턴스는 여러 호출자에 대해 스레드로부터 안전합니다. 구성 요소가 CreateProtector
에 대한 호출을 통해 IDataProtector
에 대한 참조를 가져오면 Protect
및 Unprotect
에 대한 여러 호출에 해당 참조를 사용합니다. Unprotect
에 대한 호출은 보호된 페이로드를 확인하거나 해독할 수 없는 경우 CryptographicException을 throw합니다. 일부 구성 요소는 보호 해제 작업 중에 오류를 무시하려고 할 수 있습니다. 인증 쿠키를 읽는 구성 요소는 이 오류를 처리하고 요청을 완전히 실패하는 대신 전혀 없는 cookie 것처럼 처리할 수 있습니다. 이 동작을 원하는 구성 요소는 모든 예외를 발생시키는 대신 특별히 CryptographicException을 catch해야 합니다.
ASP.NET Core