ASP.NET Core에 대 한 소비자 Api 개요Consumer APIs overview for ASP.NET Core

IDataProtectionProviderIDataProtector 는 소비자가 데이터 보호 시스템을 사용할 때 가장 기본이 되는 인터페이스입니다.The IDataProtectionProvider and IDataProtector interfaces are the basic interfaces through which consumers use the data protection system. 이러한 인터페이스는 Microsoft.AspNetCore.DataProtection.Abstractions 패키지에 포함되어 있습니다.They're located in the Microsoft.AspNetCore.DataProtection.Abstractions package.

IDataProtectionProviderIDataProtectionProvider

공급자 인터페이스는 데이터 보호 시스템의 루트를 나타냅니다.The provider interface represents the root of the data protection system. 그러나 이 인터페이스를 데이터 보호나 보호 해제 작업에 직접 사용할 수는 없습니다.It cannot directly be used to protect or unprotect data. 대신 소비자는 IDataProtectionProvider.CreateProtector(purpose) 를 호출해서 IDataProtector¨의 참조를 가져와야 하며, 여기서 "용도"는 사용 사례에 관한 소비자의 의도를 설명하는 문자열입니다.Instead, the consumer must get a reference to an IDataProtector by calling IDataProtectionProvider.CreateProtector(purpose), where purpose is a string that describes the intended consumer use case. 이 매개 변수의 의미와 적절한 값을 선택하는 방법에 대한 자세한 내용은 용도 문자열 을 참조하세요.See Purpose Strings for much more information on the intent of this parameter and how to choose an appropriate value.

IDataProtectorIDataProtector

보호자 인터페이스는 CreateProtector 호출에 의해 반환되며, 바로 이 인터페이스를 사용하여 소비자는 보호 및 보호 해제 작업을 수행할 수 있습니다.The protector interface is returned by a call to CreateProtector, and it's this interface which consumers can use to perform protect and unprotect operations.

데이터를 보호하려면 데이터를 Protect 메서드에 전달하면 됩니다.To protect a piece of data, pass the data to the Protect method. 기본 인터페이스는 byte[]를 byte[]로 변환하는 메서드를 정의하지만, 문자열을 문자열로 변환하는 오버로드 메서드도 (확장 메서드의 형태로) 제공됩니다.The basic interface defines a method which converts byte[] -> byte[], but there's also an overload (provided as an extension method) which converts string -> string. 두 메서드의 결과는 보안적으로 동일하므로 개발자는 자신의 상황에 가장 적합한 오버로드를 선택하면 됩니다.The security offered by the two methods is identical; the developer should choose whichever overload is most convenient for their use case. 어떤 오버로드 메서드를 선택해도 Protect 메서드에서 반환된 값은 이제 보호되며 (암호화 및 변조 방지되며), 응용 프로그램은 이 값을 신뢰할 수 없는 클라이언트로 전송할 수 있습니다.Irrespective of the overload chosen, the value returned by the Protect method is now protected (enciphered and tamper-proofed), and the application can send it to an untrusted client.

보호된 데이터를 다시 보호 해제하려면 보호된 데이터를 Unprotect 메서드에 전달하면 됩니다.To unprotect a previously-protected piece of data, pass the protected data to the Unprotect method. (개발자의 편의를 위해서 byte[]를 byte[]로 변환하는 오버로드와 문자열을 문자열로 변환하는 오버로드가 모두 제공됩니다.) 동일한 IDataProtector 인스턴스의 Protect 메서드를 호출해서 생성된 보호된 페이로드의 경우 Unprotect 메서드를 호출하면 보호 해제된 원본 페이로드가 반환됩니다.(There are byte[]-based and string-based overloads for developer convenience.) If the protected payload was generated by an earlier call to Protect on this same IDataProtector, the Unprotect method will return the original unprotected payload. 그러나 보호된 페이로드가 변조됐거나 다른 IDataProtector 인스턴스에 의해 만들어진 페이로드일 경우 Unprotect 메서드가 CryptographicException을 던집니다.If the protected payload has been tampered with or was produced by a different IDataProtector, the Unprotect method will throw CryptographicException.

IDataProtector 의 동일 여부를 판단하는 기준은 용도의 개념과 밀접한 관계를 갖고 있습니다.The concept of same vs. different IDataProtector ties back to the concept of purpose. 비록 두 IDataProtector 인스턴스가 동일한 루트 IDataProtectionProvider 로부터 생성되었더라도, IDataProtectionProvider.CreateProtector 를 호출할 때 서로 다른 용도 문자열을 지정했다면, 두 인스턴스는 별개의 보호자 로 간주되며, 서로 다른 인스턴스가 보호한 페이로드를 보호 해제할 수 없습니다.If two IDataProtector instances were generated from the same root IDataProtectionProvider but via different purpose strings in the call to IDataProtectionProvider.CreateProtector, then they're considered different protectors, and one won't be able to unprotect payloads generated by the other.

인터페이스 소비하기Consuming these interfaces

DI-인식 구성 요소의 경우, 구성 요소의 생성자에서 IDataProtectionProvider 매개 변수를 전달 받고, 구성 요소의 인스턴스가 만들어질 때 DI 시스템이 자동으로 이 서비스를 제공하는 방식으로 사용하도록 만들어졌습니다.For a DI-aware component, the intended usage is that the component take an IDataProtectionProvider parameter in its constructor and that the DI system automatically provides this service when the component is instantiated.

참고

일부 응용 프로그램(예: 콘솔 응용 프로그램 또는 ASP.NET 4.x 응용 프로그램)은 DI를 인식하지 못할 수도 있으므로 본문에서 설명하는 메커니즘을 사용할 수 없습니다.Some applications (such as console applications or ASP.NET 4.x applications) might not be DI-aware so cannot use the mechanism described here. 이러한 시나리오의 경우, DI를 거치지 않고 IDataProtection 공급자의 인스턴스를 얻는 방법에 대한 자세한 정보는 비 DI-인식 시나리오 를 참조하세요.For these scenarios consult the Non DI Aware Scenarios document for more information on getting an instance of an IDataProtection provider without going through DI.

다음 예제는 세 가지 개념을 보여줍니다.The following sample demonstrates three concepts:

  1. 추가 데이터 보호 시스템 서비스 컨테이너를Add the data protection system to the service container,

  2. DI를 통해서 IDataProtectionProvider 의 인스턴스 가져오기Using DI to receive an instance of an IDataProtectionProvider, and

  3. IDataProtectionProvider 로부터 IDataProtector 의 인스턴스를 생성하고, 이를 이용해서 데이터를 보호하고 보호 해제하기.Creating an IDataProtector from an IDataProtectionProvider and using it to protect and unprotect data.

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!
 */

Microsoft.AspNetCore.DataProtection.Abstractions 패키지에는 개발자의 편의를 위한 IServiceProvider.GetDataProtector 확장 메서드가 포함되어 있습니다.The package Microsoft.AspNetCore.DataProtection.Abstractions contains an extension method IServiceProvider.GetDataProtector as a developer convenience. 이 확장 메서드는 서비스 공급자에서 IDataProtectionProvider 를 얻고 IDataProtectionProvider.CreateProtector 를 호출하는 과정을 단일 작업으로 축약시켜줍니다.It encapsulates as a single operation both retrieving an IDataProtectionProvider from the service provider and calling IDataProtectionProvider.CreateProtector. 다음 예제는 이 확장 메서드의 사용 방법을 보여줍니다.The following sample demonstrates its usage.

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}");
    }
}

IDataProtectionProviderIDataProtector 의 인스턴스는 다중 호출자에 대해 스레드로부터 안전(Thread-Safe)합니다.Instances of IDataProtectionProvider and IDataProtector are thread-safe for multiple callers. 구성 요소에서 CreateProtector 를 호출해서 IDataProtector 의 참조를 얻은 다음, 이 참조를 이용해서 ProtectUnprotect 를 반복적으로 호출할 수 있도록 만들어졌습니다.It's intended that once a component gets a reference to an IDataProtector via a call to CreateProtector, it will use that reference for multiple calls to Protect and Unprotect. Unprotect 호출 시 보호된 페이로드를 검증하거나 판독할 수 없으면 CryptographicException이 던져집니다.A call to Unprotect will throw CryptographicException if the protected payload cannot be verified or deciphered. 일부 구성 요소는 보호 해제 작업 중 발생하는 오류를 무시해야 하는 경우도 있는데, 가령 인증 쿠키를 읽는 구성 요소는 요청 자체를 실패시키는 대신 이 오류를 처리하여 쿠키가 아예 존재하지 않는 것처럼 동작할 수 있습니다.Some components may wish to ignore errors during unprotect operations; a component which reads authentication cookies might handle this error and treat the request as if it had no cookie at all rather than fail the request outright. 이런 동작이 필요한 구성 요소는 모든 예외를 감춰버리는 대신 명확하게 CryptographicException만 잡아야 합니다.Components which want this behavior should specifically catch CryptographicException instead of swallowing all exceptions.