예제 #1
0
        public virtual async Task <JwtSignInResult> RefreshTokenAsync(string refreshToken)
        {
            var result = _tokenFactoryService.ValidateAndGetRefreshTokenUserIdAndSecurity(refreshToken);

            if (result.UserId == null || result.SecurityStamp == null)
            {
                return(JwtSignInResult.Failed("invalid token"));
            }

            var user = await UserManager.FindByIdAsync(result.UserId);

            if (user == null || !await ValidateSecurityStampAsync(user, result.SecurityStamp))
            {
                return(JwtSignInResult.Failed("token expired"));
            }

            IList <Claim> additionalClaims;

            if (!string.IsNullOrEmpty(result.AmrCliam))
            {
                additionalClaims = new List <Claim>();

                additionalClaims.Add(new Claim("amr", result.AmrCliam));
            }
            else
            {
                additionalClaims = Array.Empty <Claim>();
            }

            var tokens = await SignInWithClaimsAsync(user, additionalClaims);

            return(JwtSignInResult.Success(tokens));
        }
예제 #2
0
        public virtual async Task <JwtSignInResult> TwoFactorRecoveryCodeSignInAsync(string recoveryCode)
        {
            var twoFactorInfo = RetrieveTwoFactorInfoAsync();

            if (twoFactorInfo == null || twoFactorInfo.UserId == null)
            {
                return(JwtSignInResult.Failed());
            }

            var user = await UserManager.FindByIdAsync(twoFactorInfo.UserId);

            if (user == null)
            {
                return(JwtSignInResult.Failed());
            }

            var result = await UserManager.RedeemTwoFactorRecoveryCodeAsync(user, recoveryCode);

            if (result.Succeeded)
            {
                return(await DoTwoFactorSignInAsync(user, twoFactorInfo, rememberClient : false));
            }

            // We don't protect against brute force attacks since codes are expected to be random.
            return(JwtSignInResult.Failed());
        }
예제 #3
0
        public virtual async Task <JwtSignInResult> TwoFactorSignInAsync(string provider, string code, bool rememberClient = false)
        {
            if (rememberClient)
            {
                throw new NotSupportedException(nameof(rememberClient));
            }

            var twoFactorInfo = RetrieveTwoFactorInfoAsync();

            if (twoFactorInfo == null || twoFactorInfo.UserId == null)
            {
                return(JwtSignInResult.Failed());
            }
            var user = await UserManager.FindByIdAsync(twoFactorInfo.UserId);

            if (user == null)
            {
                return(JwtSignInResult.Failed());
            }

            var error = await PreSignInCheck(user);

            if (error != null)
            {
                return(error);
            }
            if (await UserManager.VerifyTwoFactorTokenAsync(user, provider, code))
            {
                return(await DoTwoFactorSignInAsync(user, twoFactorInfo, rememberClient));
            }
            // If the token is incorrect, record the failure which also may cause the user to be locked out
            await UserManager.AccessFailedAsync(user);

            return(JwtSignInResult.Failed());
        }
예제 #4
0
        private async Task <JwtSignInResult> DoTwoFactorSignInAsync(TUser user, TwoFactorAuthenticationInfo twoFactorInfo, bool rememberClient)
        {
            // When token is verified correctly, clear the access failed count used for lockout
            await ResetLockout(user);

            var claims = new List <Claim>();

            claims.Add(new Claim("amr", "mfa"));

            // Cleanup external cookie
            if (twoFactorInfo.LoginProvider != null)
            {
                claims.Add(new Claim(ClaimTypes.AuthenticationMethod, twoFactorInfo.LoginProvider));
                //await Context.SignOutAsync(IdentityConstants.ExternalScheme);
            }

            // todo: review + no need
            // Cleanup two factor user id cookie
            //await Context.SignOutAsync(IdentityConstants.TwoFactorUserIdScheme);

            string rememberTwoFactor = null;

            if (rememberClient)
            {
                rememberTwoFactor = await RememberTwoFactorClientAsync(user);
            }

            var tokens = await SignInWithClaimsAsync(user, claims);

            return(JwtSignInResult.Success(tokens));
        }
        public virtual async Task <JwtSignInResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure)
        {
            TUser val = await UserManager.FindByNameAsync(userName);

            if (val == null)
            {
                return(JwtSignInResult.Failed("invalid user name or password"));
            }
            return(await PasswordSignInAsync(val, password, isPersistent, lockoutOnFailure));
        }
        public virtual async Task <JwtSignInResult> CheckPasswordSignInAsync(TUser user, string password, bool lockoutOnFailure)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var error = await PreSignInCheck(user);

            if (error != null)
            {
                return(error);
            }

            if (await UserManager.CheckPasswordAsync(user, password))
            {
                var alwaysLockout = AppContext.TryGetSwitch("Microsoft.AspNetCore.Identity.CheckPasswordSignInAlwaysResetLockoutOnSuccess", out var enabled) && enabled;
                // Only reset the lockout when not in quirks mode if either TFA is not enabled or the client is remembered for TFA.
                if (alwaysLockout || !await IsTfaEnabled(user) || await IsTwoFactorClientRememberedAsync(user))
                {
                    await ResetLockout(user);
                }

                return(JwtSignInResult.Success(null));
            }

            Logger.LogWarning(2, "User failed to provide the correct password.");

            if (UserManager.SupportsUserLockout && lockoutOnFailure)
            {
                // If lockout is requested, increment access failed count which might lock out the user
                await UserManager.AccessFailedAsync(user);

                if (await UserManager.IsLockedOutAsync(user))
                {
                    return(await LockedOut(user));
                }
            }
            return(JwtSignInResult.Failed());
        }
예제 #7
0
        protected virtual async Task <JwtSignInResult> SignInOrTwoFactorAsync(TUser user,
                                                                              string loginProvider = null,
                                                                              bool bypassTwoFactor = false)
        {
            if (!bypassTwoFactor && await IsTfaEnabled(user))
            {
                if (!await IsTwoFactorClientRememberedAsync(user))
                {
                    // Store the userId for use after two factor check
                    var userId = await UserManager.GetUserIdAsync(user);

                    var twoFactorStepOneToken = StoreTwoFactorInfo(userId, loginProvider);
                    return(JwtSignInResult.TwoFactorRequired(twoFactorStepOneToken));
                }
            }

            if (loginProvider != null)
            {
                // no need for jwt token!?
                // await Context.SignOutAsync(IdentityConstants.ExternalScheme);
            }

            CreateJwtTokenResult createJwtTokenResult;

            if (loginProvider == null)
            {
                createJwtTokenResult = await SignInWithClaimsAsync(user, new Claim[] { new Claim("amr", "pwd") });
            }
            else
            {
                IList <Claim> additionalClaims = Array.Empty <Claim>();
                createJwtTokenResult = await SignInWithClaimsAsync(user, additionalClaims);
            }

            return(JwtSignInResult.Success(createJwtTokenResult));
        }