Esempio n. 1
0
    public async Task <ActionResult <IEnumerable <string> > > Get2FAProviders()
    {
        BackOfficeIdentityUser?user = await _signInManager.GetTwoFactorAuthenticationUserAsync();

        if (user == null)
        {
            _logger.LogWarning("Get2FAProviders :: No verified user found, returning 404");
            return(NotFound());
        }

        IEnumerable <string> userFactors = await _twoFactorLoginService.GetEnabledTwoFactorProviderNamesAsync(user.Key);

        return(new ObjectResult(userFactors));
    }
Esempio n. 2
0
    public async Task <IActionResult> Verify2FACode(Verify2FACodeModel model, string?returnUrl = null)
    {
        MemberIdentityUser?user = await _memberSignInManager.GetTwoFactorAuthenticationUserAsync();

        if (user == null !)
        {
            _logger.LogWarning("PostVerify2FACode :: No verified member found, returning 404");
            return(NotFound());
        }

        if (ModelState.IsValid)
        {
            SignInResult result = await _memberSignInManager.TwoFactorSignInAsync(
                model.Provider,
                model.Code,
                model.IsPersistent,
                model.RememberClient);

            if (result.Succeeded && returnUrl is not null)
            {
                return(RedirectToLocal(returnUrl));
            }

            if (result.IsLockedOut)
            {
                ModelState.AddModelError(nameof(Verify2FACodeModel.Code), "Member is locked out");
            }
            else if (result.IsNotAllowed)
            {
                ModelState.AddModelError(nameof(Verify2FACodeModel.Code), "Member is not allowed");
            }
            else
            {
                ModelState.AddModelError(nameof(Verify2FACodeModel.Code), "Invalid code");
            }
        }

        // We need to set this, to ensure we show the 2fa login page
        IEnumerable <string> providerNames =
            await _twoFactorLoginService.GetEnabledTwoFactorProviderNamesAsync(user.Key);

        ViewData.SetTwoFactorProviderNames(providerNames);
        return(CurrentUmbracoPage());
    }
Esempio n. 3
0
        public async Task <IActionResult> ExternalLoginCallback(string returnUrl)
        {
            var errors = new List <string>();

            ExternalLoginInfo?loginInfo = await _memberSignInManager.GetExternalLoginInfoAsync();

            if (loginInfo is null)
            {
                errors.Add("Invalid response from the login provider");
            }
            else
            {
                SignInResult result = await _memberSignInManager.ExternalLoginSignInAsync(loginInfo, false, _securitySettings.Value.MemberBypassTwoFactorForExternalLogins);

                if (result == SignInResult.Success)
                {
                    // Update any authentication tokens if succeeded
                    await _memberSignInManager.UpdateExternalAuthenticationTokensAsync(loginInfo);

                    return(RedirectToLocal(returnUrl));
                }

                if (result == SignInResult.TwoFactorRequired)
                {
                    MemberIdentityUser attemptedUser =
                        await _memberManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey);

                    if (attemptedUser == null)
                    {
                        return(new ValidationErrorResult(
                                   $"No local user found for the login provider {loginInfo.LoginProvider} - {loginInfo.ProviderKey}"));
                    }


                    var providerNames = await _twoFactorLoginService.GetEnabledTwoFactorProviderNamesAsync(attemptedUser.Key);

                    ViewData.SetTwoFactorProviderNames(providerNames);

                    return(CurrentUmbracoPage());
                }

                if (result == SignInResult.LockedOut)
                {
                    errors.Add(
                        $"The local member {loginInfo.Principal.Identity?.Name} for the external provider {loginInfo.ProviderDisplayName} is locked out.");
                }
                else if (result == SignInResult.NotAllowed)
                {
                    // This occurs when SignInManager.CanSignInAsync fails which is when RequireConfirmedEmail , RequireConfirmedPhoneNumber or RequireConfirmedAccount fails
                    // however since we don't enforce those rules (yet) this shouldn't happen.
                    errors.Add(
                        $"The member {loginInfo.Principal.Identity?.Name} for the external provider {loginInfo.ProviderDisplayName} has not confirmed their details and cannot sign in.");
                }
                else if (result == SignInResult.Failed)
                {
                    // Failed only occurs when the user does not exist
                    errors.Add("The requested provider (" + loginInfo.LoginProvider +
                               ") has not been linked to an account, the provider must be linked before it can be used.");
                }
                else if (result == MemberSignInManager.ExternalLoginSignInResult.NotAllowed)
                {
                    // This occurs when the external provider has approved the login but custom logic in OnExternalLogin has denined it.
                    errors.Add(
                        $"The user {loginInfo.Principal.Identity?.Name} for the external provider {loginInfo.ProviderDisplayName} has not been accepted and cannot sign in.");
                }
                else if (result == MemberSignInManager.AutoLinkSignInResult.FailedNotLinked)
                {
                    errors.Add("The requested provider (" + loginInfo.LoginProvider +
                               ") has not been linked to an account, the provider must be linked from the back office.");
                }
                else if (result == MemberSignInManager.AutoLinkSignInResult.FailedNoEmail)
                {
                    errors.Add(
                        $"The requested provider ({loginInfo.LoginProvider}) has not provided the email claim {ClaimTypes.Email}, the account cannot be linked.");
                }
                else if (result is MemberSignInManager.AutoLinkSignInResult autoLinkSignInResult &&
                         autoLinkSignInResult.Errors.Count > 0)
                {
                    errors.AddRange(autoLinkSignInResult.Errors);
                }
Esempio n. 4
0
        public async Task <IActionResult> HandleLogin([Bind(Prefix = "loginModel")] LoginModel model)
        {
            if (ModelState.IsValid == false)
            {
                return(CurrentUmbracoPage());
            }

            MergeRouteValuesToModel(model);

            // Sign the user in with username/password, this also gives a chance for developers to
            // custom verify the credentials and auto-link user accounts with a custom IBackOfficePasswordChecker
            SignInResult result = await _signInManager.PasswordSignInAsync(
                model.Username, model.Password, isPersistent : model.RememberMe, lockoutOnFailure : true);

            if (result.Succeeded)
            {
                TempData["LoginSuccess"] = true;

                // If there is a specified path to redirect to then use it.
                if (model.RedirectUrl.IsNullOrWhiteSpace() == false)
                {
                    // Validate the redirect URL.
                    // If it's not a local URL we'll redirect to the root of the current site.
                    return(Redirect(Url.IsLocalUrl(model.RedirectUrl)
                        ? model.RedirectUrl
                        : CurrentPage !.AncestorOrSelf(1) !.Url(PublishedUrlProvider)));
                }

                // Redirect to current URL by default.
                // This is different from the current 'page' because when using Public Access the current page
                // will be the login page, but the URL will be on the requested page so that's where we need
                // to redirect too.
                return(RedirectToCurrentUmbracoUrl());
            }

            if (result.RequiresTwoFactor)
            {
                MemberIdentityUser attemptedUser = await _memberManager.FindByNameAsync(model.Username);

                if (attemptedUser == null)
                {
                    return(new ValidationErrorResult(
                               $"No local member found for username {model.Username}"));
                }

                var providerNames = await _twoFactorLoginService.GetEnabledTwoFactorProviderNamesAsync(attemptedUser.Key);

                ViewData.SetTwoFactorProviderNames(providerNames);
            }
            else if (result.IsLockedOut)
            {
                ModelState.AddModelError("loginModel", "Member is locked out");
            }
            else if (result.IsNotAllowed)
            {
                ModelState.AddModelError("loginModel", "Member is not allowed");
            }
            else
            {
                ModelState.AddModelError("loginModel", "Invalid username or password");
            }
            return(CurrentUmbracoPage());
        }