ASP.NET 5 Identity 3 users get signed out after some time

后端 未结 2 1529
长情又很酷
长情又很酷 2021-01-21 12:39

I\'m, using RC1 bits and external (Google) authentication, no Identity.EntityFramework.

During login, I set \'Remember me\' flag.

Logged-in user survives browser

相关标签:
2条回答
  • 2021-01-21 13:11

    Wow, I solved it!

    TL;DR

    I need to implement IUserSecurityStampStore<User> on my custom UserManager (aka SportCmsDb).

    Details

    During AddIdentity call (in Startup.cs ConfigureServices method) IdentityOptions are configured with default instance of IdentityCookieOptions. In constructor of IdentityCookieOptions instance of ApplicationCookie (of type CookieAuthenticationOptions) is created with handler CookieAuthenticationEvents.OnValidatePrincipal set to SecurityStampValidator.ValidatePrincipalAsync static method.

    During UseIdentity call (in Startup.cs Configure method) CookieAuthenticationMiddleware is configured with IdentityOptions.Cookies.ApplicationCookie options.

    CookieAuthenticationHandler (created by CookieAuthenticationMiddleware) in it's HandleAuthenticateAsync method reads ticket from cookie and call Options.Events.ValidatePrincipal handler for validation.

    Effectively, SecurityStampValidator.ValidatePrincipalAsync is called. This method checks that enough time has elapsed since cookie was issued (30 min by default) and calls ISecurityStampValidator.validateAsync (lines 81-82).

    Default implementation of ISecurityStampValidator is SecurityStampValidator<TUser>. It calls SignInManager<TUser>.ValidateSecurityStampAsync and when null is returned - rejects principal and forces user to sign out (lines 30-40).

    SignInManager<TUser> in its ValidateSecurityStampAsync method tries to read security stamp from User and returns null if it can't (if UserManager<User> does not supports this interface) or stamp does not match saved one (in cookie).

    My custom UserManager does not implement IUserSecurityStampStore<User>. Bingo.

    0 讨论(0)
  • 2021-01-21 13:21

    Thank you very much for the previous answers, I worked with this problem today and I resolve with this:

    1.- Custom UserStore.cs:

    public class UserStore : IUserStore<User>,                                                                                              
        IUserPasswordStore<User>,                                                                                                           
        IUserEmailStore<User>,                                                                                                              
        IUserRoleStore<User>,                                                                                                               
        IUserSecurityStampStore<User>                                                                                                       
    {  
        //omitted...
    
        public Task SetSecurityStampAsync(User user, string stamp, CancellationToken cancellationToken = default(CancellationToken))
        {
            user.SecurityStamp = stamp;
            return Task.FromResult(0);
        }
    
        public Task<string> GetSecurityStampAsync(User user, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (user.SecurityStamp == null) {
                return Task.FromResult("AspNet.Identity.SecurityStamp");
            }
            return Task.FromResult(user.SecurityStamp);
        }
    }
    

    2.- In User.cs And DB Table User add SecurityStamp as string.

    For TEST change default 30m to 1m in Startup.cs:

    services.Configure<SecurityStampValidatorOptions>(options => {        
        options.ValidationInterval = TimeSpan.FromMinutes(1);                  
    });
    
    0 讨论(0)
提交回复
热议问题