ResetPassword Token How and where is it stored?

I was trying to figure out how password reset and account confirmation works in ASP.NET Identity. I just would like to know if tokens are stored and if so where?

The links I get when I use the password reset function look something like this.

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

      

My guess is the tokens are stored in the link itself, as I cannot find it anywhere else. Maybe someone knows for sure?

+4


source to share


2 answers


As I mentioned in the comment



"Tokens are generated using SecurityStamp and verified using SecurityStamp and are not stored anywhere in the database or local file storage. If you update SecurityStamp, the previous tokens are no longer valid."

+10


source


@DSR is correct, but I would like to add some information to this as well.

If you set up a web project from Individual User Accounts

go to Individual User Accounts

:

App_Start -> IdentityConfig.cs

      

There you will see code like this:

var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
    manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
}

      

Description for DataProtectorTokenProvider<TUser, TKey>

gives information:

Represents a token provider that uses IDataProtector to generate encrypted tokens based on a security token.

https://docs.microsoft.com/en-us/previous-versions/aspnet/dn613280(v%3dvs.108)

However, we can try to understand a little deeper how it actually works. Token validation will fail if different ones are used to create and validate a token on the same server Application Pool Identities

. This indicates that the actual protection mechanism will look something like this:

System.Security.Cryptography.ProtectedData.Protect(userData, entropy, DataProtectionScope.CurrentUser);

      

Considering that this works if all sites use the same Application Pool Identity

it also points to Application Pool Identity

. Can also be DataProtectionProvider

with protectionDescriptor

"LOCAL=user"

. It had to work with different ones Application Pool Identities

if given 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

has a type IDataProtectionProvider

.

This is introduced in Startup.Auth.cs like this:

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

      



CreatePerOwinContext

is in assembly Microsoft.AspNet.Identity.Owin

AppBuilderExtensions.cs

. And ASP.NET Identity

and ASP.NET Core Identity

are open source and can be viewed on 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()

in turn app.GetDataProtectionProvider()

is in the assembly, Microsoft.Owin.Security

which is also Open Source.

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

We also see that it CreateDataProtector

has a fallback to implement DpapiDataProtectionProvider

.

private static IDataProtectionProvider FallbackDataProtectionProvider(IAppBuilder app)
{
    return new DpapiDataProtectionProvider(GetAppName(app));
}

      

When reading about DpapiDataProtectionProvider

(DPAPI stands for Data Protection Application Programming Interface), the description says:

Used to provide data protection services that are derived from the Data Protection API. It is the best choice for data protection when your application is not hosted in ASP.NET and all processes run under the same domain identity .

The goals of the Create method are described as:

The additional entropy used to ensure the protection of protected data can only be unprotected for the right purpose.

The class of the defender itself then looks like this:

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)

0


source







All Articles