@DSR 是正确的,但我也想为此添加一些信息。
如果您使用Individual User Accounts 设置了一个 Web 项目,请转到:
App_Start -> IdentityConfig.cs
你会看到这样的代码:
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}
DataProtectorTokenProvider<TUser, TKey> 的描述提供了信息:
表示使用 IDataProtector 生成的令牌提供程序
基于安全标记的加密令牌。
https://docs.microsoft.com/en-us/previous-versions/aspnet/dn613280(v%3dvs.108)
但是,我们可以尝试更深入地挖掘它的实际工作原理。如果使用不同的Application Pool Identities 在单个服务器上创建和验证令牌,令牌验证将失败。这表明实际的保护机制看起来像这样:
System.Security.Cryptography.ProtectedData.Protect(userData, entropy, DataProtectionScope.CurrentUser);
如果所有站点都使用相同的Application Pool Identity 点,它也可以工作。也可以是 DataProtectionProvider 和 protectionDescriptor "LOCAL=user"。如果设置了LOCAL=machine,它应该可以使用不同的Application Pool Identities。
new DataProtectionProvider("LOCAL=user")
https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.dataprotector?view=netframework-4.7.2
https://docs.microsoft.com/en-us/uwp/api/windows.security.cryptography.dataprotection.dataprotectionprovider
dataProtectionProvider 的类型为 IDataProtectionProvider。
像这样在 Startup.Auth.cs 中注入:
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
CreatePerOwinContext 位于程序集 Microsoft.AspNet.Identity.Owin -> AppBuilderExtensions.cs。 ASP.NET Identity 和 ASP.NET Core Identity 都是开源的,可以在 GitHub 上查看。
public static IAppBuilder CreatePerOwinContext<T>(this IAppBuilder app,
Func<IdentityFactoryOptions<T>, IOwinContext, T> createCallback,
Action<IdentityFactoryOptions<T>, T> disposeCallback) where T : class, IDisposable
{
if (app == null)
{
throw new ArgumentNullException("app");
}
if (createCallback == null)
{
throw new ArgumentNullException("createCallback");
}
if (disposeCallback == null)
{
throw new ArgumentNullException("disposeCallback");
}
app.Use(typeof (IdentityFactoryMiddleware<T, IdentityFactoryOptions<T>>),
new IdentityFactoryOptions<T>
{
DataProtectionProvider = app.GetDataProtectionProvider(),
Provider = new IdentityFactoryProvider<T>
{
OnCreate = createCallback,
OnDispose = disposeCallback
}
});
return app;
}
https://github.com/aspnet/AspNetIdentity/blob/master/src/Microsoft.AspNet.Identity.Owin/Extensions/AppBuilderExtensions.cs
https://archive.codeplex.com/?p=aspnetidentity#src/Microsoft.AspNet.Identity.Owin/Extensions/AppBuilderExtensions.cs
app.GetDataProtectionProvider() 又位于程序集Microsoft.Owin.Security 中,这也是开源的。
public static IDataProtectionProvider GetDataProtectionProvider(this IAppBuilder app)
{
if (app == null)
{
throw new ArgumentNullException("app");
}
object value;
if (app.Properties.TryGetValue("security.DataProtectionProvider", out value))
{
var del = value as DataProtectionProviderDelegate;
if (del != null)
{
return new CallDataProtectionProvider(del);
}
}
return null;
}
https://github.com/aspnet/AspNetKatana/blob/release/src/Microsoft.Owin.Security/DataProtection/AppBuilderExtensions.cs
我们还可以看到CreateDataProtector 有一个回退到实现DpapiDataProtectionProvider。
private static IDataProtectionProvider FallbackDataProtectionProvider(IAppBuilder app)
{
return new DpapiDataProtectionProvider(GetAppName(app));
}
当阅读DpapiDataProtectionProvider(DPAPI 代表数据保护应用程序编程接口)时,描述说:
用于提供源自于
数据保护 API。是您数据保护的最佳选择
应用程序不是由 ASP.NET 托管的,所有进程都运行为
相同的域身份。
Create 方法的用途描述为:
用于确保受保护数据的附加熵只能
出于正确目的而不受保护。
保护器类本身如下所示:
using System.Security.Cryptography;
namespace Microsoft.Owin.Security.DataProtection
{
internal class DpapiDataProtector : IDataProtector
{
private readonly System.Security.Cryptography.DpapiDataProtector _protector;
public DpapiDataProtector(string appName, string[] purposes)
{
_protector = new System.Security.Cryptography.DpapiDataProtector(appName, "Microsoft.Owin.Security.IDataProtector", purposes)
{
Scope = DataProtectionScope.CurrentUser
};
}
public byte[] Protect(byte[] userData)
{
return _protector.Protect(userData);
}
public byte[] Unprotect(byte[] protectedData)
{
return _protector.Unprotect(protectedData);
}
}
}
https://docs.microsoft.com/en-us/previous-versions/aspnet/dn253784(v%3dvs.113)