【问题标题】:ResetPassword Token How and where is it stored?ResetPassword Token 它是如何以及在哪里存储的?
【发布时间】:2014-11-20 12:44:10
【问题描述】:

我一直在尝试了解重置密码和帐户确认在 ASP.NET Identity 中的工作原理。我只想知道令牌是否被存储,如果是,在哪里?

我在使用密码重置功能时收到的链接如下所示

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

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

【问题讨论】:

  • 令牌是使用 SecurityStamp 生成的,并根据 SecurityStamp 进行验证,而不是存储在数据库或本地文件存储中的任何位置。如果您更新 SecurityStamp,则以前的令牌将不再有效。

标签: asp.net asp.net-identity


【解决方案1】:

正如我在评论中提到的

“使用 SecurityStamp 生成令牌并根据 SecurityStamp 进行验证,而不是存储在数据库或本地文件存储中的任何位置。如果您更新 SecurityStamp,则以前的令牌不再有效。”

【讨论】:

    【解决方案2】:

    @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&lt;TUser, TKey&gt; 的描述提供了信息:

    表示使用 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"。如果设置了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.csASP.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)

    【讨论】:

      猜你喜欢
      • 2018-02-22
      • 2023-03-14
      • 2014-04-25
      • 2013-07-07
      • 1970-01-01
      • 2021-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多