ResetPassword Token它存储的方式和位置?

时间:2014-11-20 12:44:11

标签: asp.net asp.net-identity

我一直在试图了解重置密码和密码的方式。帐户确认在ASP.NET身份中有效。我想知道是否存储了令牌,如果存储,那么在哪里?

我使用密码重置功能时收到的链接看起来像这样

http://localhost:1470/Account/ResetPassword?userId=a8b1389c-df93-4dfc-b463-541507c1a4bc&code=yhUegXIM9SZBpPVbBtv22kg7NO7F96B8MJi9MryAadUY5XYjz8srVkS5UL8Lx%2BLPYTU6a6jhqOrzMUkkMyPbEHPY3Ul6%2B%2F0s0qQvtM%2FLLII3s29FgkcK0OnjX46Bmj9JlFCUx53rOH%2FXMacwnKDzoJ1rbrUyypZiJXloIE50Q6iPuMTUHbX9O%2B3JMZtCVXjhhsHLkTOn9IVoN6uVAOMWNQ%3D%3D

我的猜测是令牌存储在链接本身,因为我在其他地方找不到任何痕迹。也许有人确切知道?

2 个答案:

答案 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也是可行的。也可以是DataProtectionProviderprotectionDescriptor "LOCAL=user"。如果设置了Application Pool Identities,它应该与其他LOCAL=machine一起工作。

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 IdentityASP.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)