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

徘徊边缘 提交于 2019-12-02 00:02:52

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.

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);                  
});
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!