Custom ASP.NET Identity 2.0 UserStore - Is implementing all interfaces required?

前端 未结 3 989
醉酒成梦
醉酒成梦 2021-02-07 04:18

I\'ve created a custom IUserStore for my application. I\'ve implemented the interfaces I need,

   IUserStore,
           


        
3条回答
  •  太阳男子
    2021-02-07 04:44

    I had the same problem. For the moment, as the SignInManager.SignInOrTwoFactor method blindly checks for the GetTwoFactorAuthentication it throws an exception when the UserStore doesn't implement the IUserTwoFactorStore.

    I believe Microsoft intended that the SignInManager PasswordSignInAsync method must be overriden in a custom SignInManager class. Unfortunately I couldn't find any documentation or samples pointing so.

    Here is the SignInManager wrapper class I implemented to solve this issue:

    public class EnhancedSignInManager : SignInManager
        where TUser : class, IUser
        where TKey : IEquatable
    {
        public EnhancedSignInManager(
            UserManager userManager, 
            IAuthenticationManager authenticationManager)
            : base(userManager, authenticationManager)
        {
        }
    
        public override async Task SignInAsync(
            TUser user, 
            bool isPersistent, 
            bool rememberBrowser)
        {
            var userIdentity = await CreateUserIdentityAsync(user).WithCurrentCulture();
    
            // Clear any partial cookies from external or two factor partial sign ins
            AuthenticationManager.SignOut(
                DefaultAuthenticationTypes.ExternalCookie, 
                DefaultAuthenticationTypes.TwoFactorCookie);
    
            if (rememberBrowser)
            {
                var rememberBrowserIdentity = AuthenticationManager
                    .CreateTwoFactorRememberBrowserIdentity(ConvertIdToString(user.Id));
    
                AuthenticationManager.SignIn(
                    new AuthenticationProperties { IsPersistent = isPersistent }, 
                    userIdentity, 
                    rememberBrowserIdentity);
            }
            else
            {
                AuthenticationManager.SignIn(
                    new AuthenticationProperties { IsPersistent = isPersistent }, 
                    userIdentity);
            }
        }
    
        private async Task SignInOrTwoFactor(TUser user, bool isPersistent)
        {
            var id = Convert.ToString(user.Id);
    
            if (UserManager.SupportsUserTwoFactor 
                && await UserManager.GetTwoFactorEnabledAsync(user.Id)
                                    .WithCurrentCulture()
                && (await UserManager.GetValidTwoFactorProvidersAsync(user.Id)
                                     .WithCurrentCulture()).Count > 0
                    && !await AuthenticationManager.TwoFactorBrowserRememberedAsync(id)
                                                   .WithCurrentCulture())
            {
                var identity = new ClaimsIdentity(
                    DefaultAuthenticationTypes.TwoFactorCookie);
    
                identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, id));
    
                AuthenticationManager.SignIn(identity);
    
                return SignInStatus.RequiresVerification;
            }
            await SignInAsync(user, isPersistent, false).WithCurrentCulture();
            return SignInStatus.Success;
        }
    
        public override async Task PasswordSignInAsync(
            string userName, 
            string password, 
            bool isPersistent, 
            bool shouldLockout)
        {
            if (UserManager == null)
            {
                return SignInStatus.Failure;
            }
    
            var user = await UserManager.FindByNameAsync(userName).WithCurrentCulture();
            if (user == null)
            {
                return SignInStatus.Failure;
            }
    
            if (UserManager.SupportsUserLockout 
                && await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
            {
                return SignInStatus.LockedOut;
            }
    
            if (UserManager.SupportsUserPassword 
                && await UserManager.CheckPasswordAsync(user, password)
                                    .WithCurrentCulture())
            {
                return await SignInOrTwoFactor(user, isPersistent).WithCurrentCulture();
            }
            if (shouldLockout && UserManager.SupportsUserLockout)
            {
                // If lockout is requested, increment access failed count
                // which might lock out the user
                await UserManager.AccessFailedAsync(user.Id).WithCurrentCulture();
                if (await UserManager.IsLockedOutAsync(user.Id).WithCurrentCulture())
                {
                    return SignInStatus.LockedOut;
                }
            }
            return SignInStatus.Failure;
        }
    }
    

    I hope it helps. Cheers

提交回复
热议问题