有关 ASP.NET Core 的使用者 Api 概述Consumer APIs overview for ASP.NET Core

本文内容

IDataProtectionProviderIDataProtector 接口是使用者使用数据保护系统的基本接口。它们位于AspNetCore文件包中。

IDataProtectionProviderIDataProtectionProvider

提供程序接口表示数据保护系统的根。它不能直接用于保护或取消保护数据。相反,使用者必须通过调用 IDataProtectionProvider.CreateProtector(purpose)获取对 IDataProtector 的引用,其中目的是描述预期使用者用例的字符串。有关此参数意向的详细信息以及如何选择适当的值,请参阅目的字符串

IDataProtectorIDataProtector

保护程序接口由对 CreateProtector的调用返回,它是使用者可用于执行保护和取消保护操作的接口。

若要保护数据片段,请将数据传递到 Protect 方法。基本接口定义一个方法,该方法可将 byte [] 转换为 byte [] > byte [],但还有一个重载(提供作为扩展方法)来转换字符串 > 字符串。这两种方法提供的安全性完全相同;开发人员应选择最适合其用例的任何重载。无论选择哪种重载,protected 方法返回的值现在都受保护(到加密和篡改防),应用程序可以将其发送到不受信任的客户端。

若要取消对以前受保护的数据片段的保护,请将受保护的数据传递到 Unprotect 方法。(出于开发人员的方便,有基于字节 [] 的和基于字符串的重载。)如果在此同一 IDataProtector上对 Protect 的之前调用生成了受保护的负载,则 Unprotect 方法将返回未受保护的原始有效负载。如果受保护的负载已被篡改或由不同的 IDataProtector生成,Unprotect 方法将引发 System.security.cryptography.cryptographicexception。

相同和不同 IDataProtector 的概念将返回到目的概念。如果两个 IDataProtector 实例是从同一个根 IDataProtectionProvider 生成的,但通过调用 IDataProtectionProvider.CreateProtector的不同目的字符串生成的,则它们将被视为不同的保护程序,而一个将无法取消保护由另一个生成的负载。

使用这些接口Consuming these interfaces

对于支持 DI 的组件,预期的用法是组件在其构造函数中采用 IDataProtectionProvider 参数,而 DI 系统会在组件实例化时自动提供此服务。

备注

某些应用程序(如控制台应用程序或 ASP.NET 4.x 应用程序)可能不能识别 DI,因此不能使用此处所述的机制。对于这些方案,请参阅非 DI 感知方案文档,以了解有关在不使用 DI 的情况下获取 IDataProtection 提供程序实例的详细信息。

下面的示例演示三个概念:

  • 将数据保护系统添加到服务容器中,

  • 使用 DI 接收 IDataProtectionProvider的实例,然后

  • 使用 IDataProtectionProvider 创建 IDataProtector,并使用它来保护数据并对其取消保护。

  1. using System;
  2. using Microsoft.AspNetCore.DataProtection;
  3. using Microsoft.Extensions.DependencyInjection;
  4. public class Program
  5. {
  6. public static void Main(string[] args)
  7. {
  8. // add data protection services
  9. var serviceCollection = new ServiceCollection();
  10. serviceCollection.AddDataProtection();
  11. var services = serviceCollection.BuildServiceProvider();
  12. // create an instance of MyClass using the service provider
  13. var instance = ActivatorUtilities.CreateInstance<MyClass>(services);
  14. instance.RunSample();
  15. }
  16. public class MyClass
  17. {
  18. IDataProtector _protector;
  19. // the 'provider' parameter is provided by DI
  20. public MyClass(IDataProtectionProvider provider)
  21. {
  22. _protector = provider.CreateProtector("Contoso.MyClass.v1");
  23. }
  24. public void RunSample()
  25. {
  26. Console.Write("Enter input: ");
  27. string input = Console.ReadLine();
  28. // protect the payload
  29. string protectedPayload = _protector.Protect(input);
  30. Console.WriteLine($"Protect returned: {protectedPayload}");
  31. // unprotect the payload
  32. string unprotectedPayload = _protector.Unprotect(protectedPayload);
  33. Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
  34. }
  35. }
  36. }
  37. /*
  38. * SAMPLE OUTPUT
  39. *
  40. * Enter input: Hello world!
  41. * Protect returned: CfDJ8ICcgQwZZhlAlTZT...OdfH66i1PnGmpCR5e441xQ
  42. * Unprotect returned: Hello world!
  43. */

包 AspNetCore 包含扩展方法 IServiceProvider.GetDataProtector 作为开发人员的便利。它封装为一个操作,从服务提供程序检索 IDataProtectionProvider,并调用 IDataProtectionProvider.CreateProtector下面的示例演示了其用法。

  1. using System;
  2. using Microsoft.AspNetCore.DataProtection;
  3. using Microsoft.Extensions.DependencyInjection;
  4. public class Program
  5. {
  6. public static void Main(string[] args)
  7. {
  8. // add data protection services
  9. var serviceCollection = new ServiceCollection();
  10. serviceCollection.AddDataProtection();
  11. var services = serviceCollection.BuildServiceProvider();
  12. // get an IDataProtector from the IServiceProvider
  13. var protector = services.GetDataProtector("Contoso.Example.v2");
  14. Console.Write("Enter input: ");
  15. string input = Console.ReadLine();
  16. // protect the payload
  17. string protectedPayload = protector.Protect(input);
  18. Console.WriteLine($"Protect returned: {protectedPayload}");
  19. // unprotect the payload
  20. string unprotectedPayload = protector.Unprotect(protectedPayload);
  21. Console.WriteLine($"Unprotect returned: {unprotectedPayload}");
  22. }
  23. }

提示

IDataProtectionProviderIDataProtector 的实例对于多个调用方是线程安全的。它的目的是,在组件通过调用 CreateProtector获取对 IDataProtector 的引用时,它会将该引用用于多次调用 ProtectUnprotect如果无法验证或解密受保护的有效负载,则对 Unprotect 的调用将引发 System.security.cryptography.cryptographicexception。某些组件可能希望在取消保护操作期间忽略错误;读取身份验证 cookie 的组件可能会处理此错误,并将请求视为根本没有 cookie,而不是完全失败的请求。需要此行为的组件应专门捕获 System.security.cryptography.cryptographicexception,而不是抑制所有异常。