我一直在试图了解重置密码和密码的方式。帐户确认在ASP.NET身份中有效。我想知道是否存储了令牌,如果存储,那么在哪里?
我使用密码重置功能时收到的链接看起来像这样
http://localhost:1470/Account/ResetPassword?userId=a8b1389c-df93-4dfc-b463-541507c1a4bc&code=yhUegXIM9SZBpPVbBtv22kg7NO7F96B8MJi9MryAadUY5XYjz8srVkS5UL8Lx%2BLPYTU6a6jhqOrzMUkkMyPbEHPY3Ul6%2B%2F0s0qQvtM%2FLLII3s29FgkcK0OnjX46Bmj9JlFCUx53rOH%2FXMacwnKDzoJ1rbrUyypZiJXloIE50Q6iPuMTUHbX9O%2B3JMZtCVXjhhsHLkTOn9IVoN6uVAOMWNQ%3D%3D
我的猜测是令牌存储在链接本身,因为我在其他地方找不到任何痕迹。也许有人确切知道?
答案 0 :(得分:10)
正如我在评论中提到的那样
"令牌是使用SecurityStamp生成的,并且针对SecurityStamp进行验证,而不是存储在数据库或本地文件存储中的任何位置。如果更新SecurityStamp,则之前的令牌不再有效。"
答案 1 :(得分:0)
@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"
。如果设置了Application Pool Identities
,它应该与其他LOCAL=machine
一起工作。
new DataProtectionProvider("LOCAL=user")
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;
}
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;
}
我们还可以看到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)