Skip to content

Latest commit

 

History

History
60 lines (36 loc) · 5.88 KB

File metadata and controls

60 lines (36 loc) · 5.88 KB
title author description ms.author ms.date uid
Consumer APIs overview for ASP.NET Core
tdykstra
Receive a brief overview of the various consumer APIs available within the ASP.NET Core data protection library.
tdykstra
06/11/2019
security/data-protection/consumer-apis/overview

Consumer APIs overview for ASP.NET Core

The IDataProtectionProvider and IDataProtector interfaces are the basic interfaces through which consumers use the data protection system. They're located in the Microsoft.AspNetCore.DataProtection.Abstractions package.

IDataProtectionProvider

The provider interface represents the root of the data protection system. It cannot directly be used to protect or unprotect data. 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.

IDataProtector

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.

To protect a piece of data, pass the data to the Protect method. 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. 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.

To unprotect a previously-protected piece of data, pass the protected data to the Unprotect method. (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. If the protected payload has been tampered with or was produced by a different IDataProtector, the Unprotect method will throw CryptographicException.

The concept of same vs. different IDataProtector ties back to the concept of purpose. 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

For a DI-aware component, the intended usage is that the component takes an IDataProtectionProvider parameter in its constructor and that the DI system automatically provides this service when the component is instantiated.

Note

Some applications (such as console applications or ASP.NET 4.x applications) might not be DI-aware so cannot use the mechanism described here. 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. Using DI to receive an instance of an IDataProtectionProvider, and

  3. Creating an IDataProtector from an IDataProtectionProvider and using it to protect and unprotect data.

Console app

[!code-csharp]

Web app

Call xref:Microsoft.Extensions.DependencyInjection.DataProtectionServiceCollectionExtensions.AddDataProtection(Microsoft.Extensions.DependencyInjection.IServiceCollection,System.Action{Microsoft.AspNetCore.DataProtection.DataProtectionOptions}) in Program.cs:

[!code-csharp]

The following highlighted code shows how to use xref:Microsoft.AspNetCore.DataProtection.IDataProtector in a controller:

[!code-csharp]

The package Microsoft.AspNetCore.DataProtection.Abstractions contains an extension method xref:Microsoft.AspNetCore.DataProtection.DataProtectionCommonExtensions.GetDataProtector%2A as a developer convenience. It encapsulates as a single operation both retrieving an xref:Microsoft.AspNetCore.DataProtection.IDataProtectionProvider from the service provider and calling IDataProtectionProvider.CreateProtector. The following sample demonstrates its usage:

[!code-csharp]

Tip

Instances of IDataProtectionProvider and IDataProtector are thread-safe for multiple callers. 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. 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. Components which want this behavior should specifically catch CryptographicException instead of swallowing all exceptions.