コード例 #1
0
        public override async ValueTask HandleAsync(
            OpenIddictServerEvents.HandleTokenRequestContext notification)
        {
            var request = notification.Request;

            if (!request.IsPasswordGrantType())
            {
                return;
            }

            var httpContext = notification.Transaction.GetHttpRequest().HttpContext;
            await _rateLimitService.Throttle(ZoneLimits.Login, httpContext.Connection.RemoteIpAddress.ToString(), httpContext.RequestAborted);

            var user = await _userManager.FindByNameAsync(request.Username);

            if (user == null || await _u2FService.HasDevices(user.Id) ||
                !(await _signInManager.CheckPasswordSignInAsync(user, request.Password, lockoutOnFailure: true))
                .Succeeded)
            {
                notification.Reject(
                    error: OpenIddictConstants.Errors.InvalidGrant,
                    description: "The specified credentials are invalid.");
                return;
            }

            notification.Principal = await CreateClaimsPrincipalAsync(request, user);

            notification.HandleAuthentication();
        }
コード例 #2
0
        public override async Task <OpenIddictServerEventState> HandleAsync(
            OpenIddictServerEvents.HandleTokenRequest notification)
        {
            var request = notification.Context.Request;

            if (!request.IsPasswordGrantType())
            {
                // Allow other handlers to process the event.
                return(OpenIddictServerEventState.Unhandled);
            }

            // Validate the user credentials.
            // Note: to mitigate brute force attacks, you SHOULD strongly consider
            // applying a key derivation function like PBKDF2 to slow down
            // the password validation process. You SHOULD also consider
            // using a time-constant comparer to prevent timing attacks.
            var user = await _userManager.FindByNameAsync(request.Username);

            if (user == null || await _u2FService.HasDevices(user.Id) ||
                !(await _signInManager.CheckPasswordSignInAsync(user, request.Password, lockoutOnFailure: true))
                .Succeeded)
            {
                notification.Context.Reject(
                    error: OpenIddictConstants.Errors.InvalidGrant,
                    description: "The specified credentials are invalid.");
                // Don't allow other handlers to process the event.
                return(OpenIddictServerEventState.Handled);
            }

            notification.Context.Validate(await CreateTicketAsync(request, user));
            // Don't allow other handlers to process the event.
            return(OpenIddictServerEventState.Handled);
        }
コード例 #3
0
        public async Task <IActionResult> Login(LoginViewModel model, string returnUrl = null)
        {
            if (!CanLoginOrRegister())
            {
                return(RedirectToAction("Login"));
            }
            ViewData["ReturnUrl"] = returnUrl;
            if (ModelState.IsValid)
            {
                // Require the user to have a confirmed email before they can log on.
                var user = await _userManager.FindByEmailAsync(model.Email);

                if (user != null)
                {
                    if (user.RequiresEmailConfirmation && !await _userManager.IsEmailConfirmedAsync(user))
                    {
                        ModelState.AddModelError(string.Empty,
                                                 "You must have a confirmed email to log in.");
                        return(View(model));
                    }
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                    return(View(model));
                }

                var u2fDevices = await _u2FService.HasDevices(user.Id);

                var fido2Devices = await _fido2Service.HasCredentials(user.Id);

                if (!await _userManager.IsLockedOutAsync(user) && u2fDevices || fido2Devices)
                {
                    if (await _userManager.CheckPasswordAsync(user, model.Password))
                    {
                        LoginWith2faViewModel twoFModel = null;

                        if (user.TwoFactorEnabled)
                        {
                            // we need to do an actual sign in attempt so that 2fa can function in next step
                            await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : true);

                            twoFModel = new LoginWith2faViewModel
                            {
                                RememberMe = model.RememberMe
                            };
                        }

                        return(View("SecondaryLogin", new SecondaryLoginViewModel()
                        {
                            LoginWith2FaViewModel = twoFModel,
                            LoginWithU2FViewModel = u2fDevices? await BuildU2FViewModel(model.RememberMe, user) : null,
                            LoginWithFido2ViewModel = fido2Devices? await BuildFido2ViewModel(model.RememberMe, user): null,
                        }));
                    }
                    else
                    {
                        var incrementAccessFailedResult = await _userManager.AccessFailedAsync(user);

                        ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                        return(View(model));
                    }
                }


                var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : true);

                if (result.Succeeded)
                {
                    _logger.LogInformation($"User '{user.Id}' logged in.");
                    return(RedirectToLocal(returnUrl));
                }
                if (result.RequiresTwoFactor)
                {
                    return(View("SecondaryLogin", new SecondaryLoginViewModel()
                    {
                        LoginWith2FaViewModel = new LoginWith2faViewModel()
                        {
                            RememberMe = model.RememberMe
                        }
                    }));
                }
                if (result.IsLockedOut)
                {
                    _logger.LogWarning($"User '{user.Id}' account locked out.");
                    return(RedirectToAction(nameof(Lockout)));
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                    return(View(model));
                }
            }

            // If we got this far, something failed, redisplay form
            return(View(model));
        }
コード例 #4
0
        public async Task <IActionResult> Login(LoginViewModel model, string returnUrl = null)
        {
            ViewData["ReturnUrl"] = returnUrl;
            if (ModelState.IsValid)
            {
                // Require the user to have a confirmed email before they can log on.
                var user = await _userManager.FindByEmailAsync(model.Email);

                if (user != null)
                {
                    if (user.RequiresEmailConfirmation && !await _userManager.IsEmailConfirmedAsync(user))
                    {
                        ModelState.AddModelError(string.Empty,
                                                 "Debe tener un correo electrónico confirmado para iniciar sesión.");
                        return(View(model));
                    }
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "Intento de inicio de sesión no válido.");
                    return(View(model));
                }

                if (!await _userManager.IsLockedOutAsync(user) && await _u2FService.HasDevices(user.Id))
                {
                    if (await _userManager.CheckPasswordAsync(user, model.Password))
                    {
                        LoginWith2faViewModel twoFModel = null;

                        if (user.TwoFactorEnabled)
                        {
                            // we need to do an actual sign in attempt so that 2fa can function in next step
                            await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : true);

                            twoFModel = new LoginWith2faViewModel
                            {
                                RememberMe = model.RememberMe
                            };
                        }

                        return(View("SecondaryLogin", new SecondaryLoginViewModel()
                        {
                            LoginWith2FaViewModel = twoFModel,
                            LoginWithU2FViewModel = await BuildU2FViewModel(model.RememberMe, user)
                        }));
                    }
                    else
                    {
                        var incrementAccessFailedResult = await _userManager.AccessFailedAsync(user);

                        ModelState.AddModelError(string.Empty, "Intento de inicio de sesión no válido.");
                        return(View(model));
                    }
                }


                var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure : true);

                if (result.Succeeded)
                {
                    _logger.LogInformation("Usuario conectado.");
                    return(RedirectToLocal(returnUrl));
                }
                if (result.RequiresTwoFactor)
                {
                    return(View("SecondaryLogin", new SecondaryLoginViewModel()
                    {
                        LoginWith2FaViewModel = new LoginWith2faViewModel()
                        {
                            RememberMe = model.RememberMe
                        }
                    }));
                }
                if (result.IsLockedOut)
                {
                    _logger.LogWarning("Cuenta de usuario bloqueada.");
                    return(RedirectToAction(nameof(Lockout)));
                }
                else
                {
                    ModelState.AddModelError(string.Empty, "Intento de inicio de sesión no válido.");
                    return(View(model));
                }
            }

            // If we got this far, something failed, redisplay form
            return(View(model));
        }