public async Task ValidateAsync(ResourceOwnerPasswordValidationContext context)
        {
            var user = await _userManager.FindByNameAsync(context.UserName);

            if (user != null)
            {
                if (await _signInManager.CanSignInAsync(user))
                {
                    if (_userManager.SupportsUserLockout &&
                        await _userManager.IsLockedOutAsync(user))
                    {
                        context.Result = new GrantValidationResult(IdentityServer4.Models.TokenRequestErrors.InvalidGrant);
                    }
                    else if (await _userManager.CheckPasswordAsync(user, context.Password))
                    {
                        if (_userManager.SupportsUserLockout)
                        {
                            await _userManager.ResetAccessFailedCountAsync(user);
                        }

                        var sub = await _userManager.GetUserIdAsync(user);

                        context.Result = new GrantValidationResult(sub, AuthenticationMethods.Password);
                    }
                    else if (_userManager.SupportsUserLockout)
                    {
                        await _userManager.AccessFailedAsync(user);
                    }
                }
            }
        }
예제 #2
0
        public async Task <ProjectSecurityResult> ValidatePermissions(
            string projectId,
            string userName,
            string providedPassword,
            CancellationToken cancellationToken)
        {
            var displayName     = string.Empty;
            var isAuthenticated = false;
            var canEditPosts    = false;
            var canEditPages    = false;
            var timeZoneId      = userManager.Site.TimeZoneId;

            var authUser = await userManager.FindByNameAsync(userName);

            if (authUser != null)
            {
                isAuthenticated = await userManager.CheckPasswordAsync(authUser, providedPassword);
            }

            if (isAuthenticated)
            {
                var claimsPrincipal = await signInManager.CreateUserPrincipalAsync(authUser);

                if (string.IsNullOrEmpty(projectId))
                {
                    projectId = claimsPrincipal.GetProjectId();
                }

                if (string.IsNullOrEmpty(projectId))
                {
                    var project = await projectResolver.GetCurrentProjectSettings(cancellationToken);

                    if (project != null)
                    {
                        projectId = project.Id;
                    }
                }
                if (!string.IsNullOrEmpty(projectId))
                {
                    canEditPosts = await claimsPrincipal.CanEditBlog(projectId, authorizationService);

                    canEditPages = await claimsPrincipal.CanEditPages(projectId, authorizationService);
                }

                //displayName = claimsPrincipal.GetDisplayName();
                displayName = claimsPrincipal.Identity.Name;
                if (!string.IsNullOrWhiteSpace(authUser.TimeZoneId))
                {
                    timeZoneId = authUser.TimeZoneId;
                }
            }

            var blogSecurity = new ProjectSecurityResult(displayName, projectId, isAuthenticated, canEditPosts, canEditPages, timeZoneId);

            return(blogSecurity);
        }
예제 #3
0
        public async Task <IActionResult> ForgotPassword(ForgotPasswordViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = await userManager.FindByNameAsync(model.Email);

                if (user == null || !(await userManager.IsEmailConfirmedAsync(user)))
                {
                    // Don't reveal that the user does not exist or is not confirmed
                    return(View("ForgotPasswordConfirmation"));
                }

                // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
                // Send an email with this link
                // var code = await UserManager.GeneratePasswordResetTokenAsync(user);
                // var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: Context.Request.Scheme);
                // await emailSender.SendEmailAsync(model.Email, "Reset Password",
                //    "Please reset your password by clicking here: <a href=\"" + callbackUrl + "\">link</a>");
                // return View("ForgotPasswordConfirmation");
            }

            // If we got this far, something failed, redisplay form
            return(View(model));
        }
예제 #4
0
        public virtual async Task <bool> IsExistingAccount(string email)
        {
            if (string.IsNullOrWhiteSpace(email))
            {
                return(false);
            }
            var user = await _userManager.FindByNameAsync(email);

            if (user != null)
            {
                return(true);
            }
            return(false);
        }
예제 #5
0
        public async Task <UserLoginResult> TryExternalLogin(string providedEmail = "", bool?didAcceptTerms = null)
        {
            var          template    = new LoginResultTemplate();
            IUserContext userContext = null;
            var          email       = providedEmail;

            template.ExternalLoginInfo = await signInManager.GetExternalLoginInfoAsync();

            if (template.ExternalLoginInfo == null)
            {
                template.RejectReasons.Add("signInManager.GetExternalLoginInfoAsync returned null");
            }
            else
            {
                template.User = await userManager.FindByLoginAsync(template.ExternalLoginInfo.LoginProvider, template.ExternalLoginInfo.ProviderKey);

                if (template.User == null)
                {
                    if (string.IsNullOrWhiteSpace(email))
                    {
                        email = template.ExternalLoginInfo.Principal.FindFirstValue(ClaimTypes.Email);
                    }

                    if (!string.IsNullOrWhiteSpace(email) && email.Contains("@"))
                    {
                        template.User = await userManager.FindByNameAsync(email);
                    }
                }

                if (template.User == null)
                {
                    template.User = await CreateUserFromExternalLogin(template.ExternalLoginInfo, email, didAcceptTerms);
                }
            }

            if (template.User != null)
            {
                await loginRulesProcessor.ProcessAccountLoginRules(template);
            }

            if (template.SignInResult == SignInResult.Failed && template.User != null && template.RejectReasons.Count == 0)
            {
                template.SignInResult = await signInManager.ExternalLoginSignInAsync(template.ExternalLoginInfo.LoginProvider, template.ExternalLoginInfo.ProviderKey, isPersistent : false);

                if (template.SignInResult.Succeeded)
                {
                    // TODO:
                    //update last login time
                }
            }

            if (template.User != null &&
                template.SignInResult != SignInResult.Success &&
                template.SignInResult != SignInResult.TwoFactorRequired)
            {
                //clear the external login
                await signInManager.SignOutAsync();
            }

            if (template.User != null)
            {
                userContext = new UserContext(template.User);
            }

            return(new UserLoginResult(
                       template.SignInResult,
                       template.RejectReasons,
                       userContext,
                       template.MustAcceptTerms,
                       template.NeedsAccountApproval,
                       template.NeedsEmailConfirmation,
                       template.EmailConfirmationToken,
                       template.NeedsPhoneConfirmation,
                       template.ExternalLoginInfo
                       ));
        }
예제 #6
0
        public async Task <IActionResult> Login(LoginViewModel model, string returnUrl = null)
        {
            ViewData["Title"]     = sr["Log in"];
            ViewData["ReturnUrl"] = returnUrl;
            if ((Site.CaptchaOnLogin) && (Site.RecaptchaPublicKey.Length > 0))
            {
                model.RecaptchaSiteKey = Site.RecaptchaPublicKey;
            }
            model.UseEmailForLogin           = Site.UseEmailForLogin;
            model.LoginInfoTop               = Site.LoginInfoTop;
            model.LoginInfoBottom            = Site.LoginInfoBottom;
            model.ExternalAuthenticationList = signInManager.GetExternalAuthenticationSchemes();
            // don't disable db auth if there are no social auth providers configured
            model.DisableDbAuth = Site.DisableDbAuth && Site.HasAnySocialAuthEnabled();

            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            if ((Site.CaptchaOnLogin) && (Site.RecaptchaPublicKey.Length > 0))
            {
                var recpatchaSecretKey = Site.RecaptchaPrivateKey;
                var captchaResponse    = await this.ValidateRecaptcha(Request, recpatchaSecretKey);

                if (!captchaResponse.Success)
                {
                    ModelState.AddModelError("recaptchaerror", sr["reCAPTCHA Error occured. Please try again"]);
                    return(View(model));
                }
            }

            if (userManager.Site.RequireConfirmedEmail || userManager.Site.RequireApprovalBeforeLogin)
            {
                var user = await userManager.FindByNameAsync(model.Email);

                if (user != null)
                {
                    // TODO: showing these messages is not right
                    // this can be used by a hacker to determine that an account exists
                    // need to fix this
                    // probably all of these checks should be moved into signInManager.PasswordSignInAsync
                    // so that we either redirect to show message if login was correct credentials
                    // or just show invalid login attempt otherwise

                    if (userManager.Site.RequireConfirmedEmail)
                    {
                        if (!await userManager.IsEmailConfirmedAsync(user))
                        {
                            //ModelState.AddModelError(string.Empty, "You must have a confirmed email to log in.");
                            ModelState.AddModelError(string.Empty, sr["Invalid login attempt."]);
                            return(View(model));
                        }
                    }

                    if (userManager.Site.RequireApprovalBeforeLogin)
                    {
                        if (!user.AccountApproved)
                        {
                            //ModelState.AddModelError(string.Empty, "Your account must be approved by an administrator before you can log in. If an administrator approves your account, you will receive an email notifying you that your account is ready.");
                            ModelState.AddModelError(string.Empty, sr["Invalid login attempt."]);
                            return(View(model));
                        }
                    }

                    if ((user.IsLockedOut) || (user.IsDeleted))
                    {
                        //ModelState.AddModelError(string.Empty, "Your account must be approved by an administrator before you can log in. If an administrator approves your account, you will receive an email notifying you that your account is ready.");
                        ModelState.AddModelError(string.Empty, sr["Invalid login attempt."]);
                        return(View(model));
                    }
                }
            }

            var persistent = false;

            if (userManager.Site.AllowPersistentLogin)
            {
                //TODO: hide remember me in view if persistent login not allowed  site settings
                persistent = model.RememberMe;
            }

            Microsoft.AspNetCore.Identity.SignInResult result;
            if (Site.UseEmailForLogin)
            {
                result = await signInManager.PasswordSignInAsync(
                    model.Email,
                    model.Password,
                    persistent,
                    lockoutOnFailure : false);
            }
            else
            {
                result = await signInManager.PasswordSignInAsync(
                    model.UserName,
                    model.Password,
                    persistent,
                    lockoutOnFailure : false);
            }


            if (result.Succeeded)
            {
                SiteUser user;
                if (Site.UseEmailForLogin)
                {
                    user = await userManager.FindByNameAsync(model.Email);
                }
                else
                {
                    user = await userManager.FindByNameAsync(model.UserName);
                }

                if (user != null)
                {
                    await ipAddressTracker.TackUserIpAddress(Site.Id, user.Id);
                }

                if (!string.IsNullOrEmpty(returnUrl))
                {
                    return(LocalRedirect(returnUrl));
                }

                return(this.RedirectToSiteRoot(Site));
            }
            if (result.RequiresTwoFactor)
            {
                return(RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }));
            }
            if (result.IsLockedOut)
            {
                return(View("Lockout"));
            }
            else
            {
                ModelState.AddModelError(string.Empty, sr["Invalid login attempt."]);
                return(View(model));
            }
        }
예제 #7
0
        public async Task <IActionResult> Login(LoginViewModel model, string returnUrl = null)
        {
            ViewData["Title"]     = "Log in";
            ViewData["ReturnUrl"] = returnUrl;
            if ((Site.CaptchaOnLogin) && (Site.RecaptchaPublicKey.Length > 0))
            {
                model.RecaptchaSiteKey = Site.RecaptchaPublicKey;
            }

            model.LoginInfoTop    = Site.LoginInfoTop;
            model.LoginInfoBottom = Site.LoginInfoBottom;

            if (!ModelState.IsValid)
            {
                return(View(model));
            }

            if ((Site.CaptchaOnLogin) && (Site.RecaptchaPublicKey.Length > 0))
            {
                var recpatchaSecretKey = Site.RecaptchaPrivateKey;
                var captchaResponse    = await this.ValidateRecaptcha(Request, recpatchaSecretKey);

                if (!captchaResponse.Success)
                {
                    ModelState.AddModelError("recaptchaerror", "reCAPTCHA Error occured. Please try again");
                    return(View(model));
                }
            }

            if (userManager.Site.RequireConfirmedEmail || userManager.Site.RequireApprovalBeforeLogin)
            {
                var user = await userManager.FindByNameAsync(model.Email);

                if (user != null)
                {
                    // TODO: showing these messages is not right
                    // this can be used by a hacker to determine that an account exists
                    // need to fix this
                    // probably all of these checks should be moved into signInManager.PasswordSignInAsync
                    // so that we either redirect to show message if login was correct credentials
                    // or just show invalid login attempt otherwise

                    if (userManager.Site.RequireConfirmedEmail)
                    {
                        if (!await userManager.IsEmailConfirmedAsync(user))
                        {
                            ModelState.AddModelError(string.Empty, "You must have a confirmed email to log in.");
                            return(View(model));
                        }
                    }

                    if (userManager.Site.RequireApprovalBeforeLogin)
                    {
                        if (!user.AccountApproved)
                        {
                            ModelState.AddModelError(string.Empty, "Your account must be approved by an administrator before you can log in. If an administrator approves your account, you will receive an email notifying you that your account is ready.");
                            return(View(model));
                        }
                    }

                    if (user.IsLockedOut)
                    {
                        ModelState.AddModelError(string.Empty, "Your account must be approved by an administrator before you can log in. If an administrator approves your account, you will receive an email notifying you that your account is ready.");
                        return(View(model));
                    }
                }
            }


            //TODO: we don't want to lockout on first failure, we need something more advanced
            // based on sitesettings
            //var maxFailures = userManager.Site.MaxInvalidPasswordAttempts;
            // probably need to override signInManager.PasswordSignInAsync
            // or create a new method that does what we want
            // we also need to prevent login if site requires confirmed email
            // and user email is not confirmed
            // also need to prevent login if site requires approval before new users can login
            // and user is not yet approved
            // also need a UI to manually lockout a user


            // This doesn't count login failures towards account lockout
            // To enable password failures to trigger account lockout, change to lockoutOnFailure: true
            bool persistent = false;

            if (userManager.Site.AllowPersistentLogin)
            {
                //TODO: hide remember me in view if persistent login not allowed  site settings
                persistent = model.RememberMe;
            }

            //userManager.

            var result = await signInManager.PasswordSignInAsync(
                model.Email,
                model.Password,
                persistent,
                lockoutOnFailure : false);

            if (result.Succeeded)
            {
                var user = await userManager.FindByNameAsync(model.Email);

                if (user != null)
                {
                    await ipAddressTracker.TackUserIpAddress(Site.SiteGuid, user.UserGuid);
                }

                if (!string.IsNullOrEmpty(returnUrl))
                {
                    return(LocalRedirect(returnUrl));
                }

                return(this.RedirectToSiteRoot(Site));
            }
            if (result.RequiresTwoFactor)
            {
                return(RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }));
            }
            if (result.IsLockedOut)
            {
                return(View("Lockout"));
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Invalid login attempt.");
                return(View(model));
            }
        }