public async Task TryConnectExternalLoginToUser(IdentityUser user, string providerUserId, AuthenticateResult result)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            var email               = result.Principal.Claims.FindEmail();
            var provider            = result.Properties.Items["scheme"];
            var providerDisplayName = await _authenticationSchemeProvider.GetProviderDisplayName(provider);

            var identityResult = await _userManager.AddLoginAsync(user, new UserLoginInfo(provider, providerUserId, providerDisplayName), email);

            if (!identityResult.Succeeded)
            {
                throw new Exception(identityResult.Errors.First().Description);
            }
        }
Example #2
0
        public async Task <IActionResult> OnPostConfirmationAsync(string returnUrl = null)
        {
            returnUrl = returnUrl ?? Url.Content("~/");
            // Get the information about the user from the external login provider
            var info = await _signInManager.GetExternalLoginInfoAsync();

            if (info == null)
            {
                ErrorMessage = "Error loading external login information during confirmation.";
                return(RedirectToPage("./Login", new { ReturnUrl = returnUrl }));
            }

            if (ModelState.IsValid)
            {
                var user = new IdentityUser {
                    UserName = Input.Email, Email = Input.Email
                };
                var result = await _userManager.CreateAsync(user);

                if (result.Succeeded)
                {
                    var email = info.Principal.Claims.FindEmail();
                    result = await _userManager.AddLoginAsync(user, info, email);

                    if (result.Succeeded)
                    {
                        await _signInManager.SignInAsync(user, isPersistent : false);

                        _logger.LogInformation("User created an account using {Name} provider.", info.LoginProvider);
                        return(LocalRedirect(returnUrl));
                    }
                }
                foreach (var error in result.Errors)
                {
                    ModelState.AddModelError(string.Empty, error.Description);
                }
            }

            LoginProvider = info.LoginProvider;
            ReturnUrl     = returnUrl;
            return(Page());
        }
        public async Task <IActionResult> OnGetLinkLoginCallbackAsync()
        {
            var user = await _userManager.GetUserAsync(User);

            if (user == null)
            {
                return(NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'."));
            }

            var info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));

            if (info == null)
            {
                throw new InvalidOperationException($"Unexpected error occurred loading external login info for user with ID '{user.Id}'.");
            }

            var logins = await _userManager.GetLoginsAsync(user);

            if (logins.Any(l => l.LoginProvider == info.LoginProvider && l.ProviderKey == info.ProviderKey))
            {
                StatusMessage = "The external login is already linked to your account.";
                return(RedirectToPage());
            }

            var email  = info.Principal.Claims.FindEmail();
            var result = await _userManager.AddLoginAsync(user, info, email);

            if (!result.Succeeded)
            {
                throw new InvalidOperationException($"Unexpected error occurred adding external login for user with ID '{user.Id}'.");
            }

            // Clear the existing external cookie to ensure a clean login process
            await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);

            StatusMessage = "The external login was added.";
            return(RedirectToPage());
        }
Example #4
0
        public async Task MergeUsers(TUser currentUser, TUser user)
        {
            var observer = new IdentityResultObserver();

            using (var transaction = new TransactionScope(
                       TransactionScopeOption.Required,
                       new TransactionOptions
            {
                IsolationLevel = IsolationLevel.ReadCommitted,
                Timeout = TransactionManager.DefaultTimeout
            },
                       TransactionScopeAsyncFlowOption.Enabled)
                   )
            {
                var roles = await _userManager.GetRolesAsync(user);

                var userLogins = await _userManager.GetLoginsEmailInfoAsync(user);

                var claims = await _userManager.GetClaimsAsync(user);

                var emails = _userManager.GetEmails(user);

                var existingRoles = await _userManager.GetRolesAsync(currentUser);

                var missingRoles = roles.Where(role => !existingRoles.Contains(role));
                await observer.Observe(async() => await _userManager.AddToRolesAsync(currentUser, missingRoles));

                foreach (var login in userLogins)
                {
                    await observer.Observe(async() =>
                    {
                        await _userManager.RemoveLoginAsync(user, login.UserLoginInfo.LoginProvider, login.UserLoginInfo.ProviderKey);
                        return(await _userManager.AddLoginAsync(currentUser, login.UserLoginInfo, login.Email));
                    });
                }

                foreach (var email in emails.Where(e => !userLogins.Any(l => l.Email.Equals(e.Email, StringComparison.InvariantCultureIgnoreCase))))
                {
                    await observer.Observe(async() => await _userManager.AddEmailAsync(currentUser, email.Email, email.UserLoginInfo));
                }

                if (_options.Value.MergeUnconfirmedEmails || await _userManager.IsEmailConfirmedAsync(user))
                {
                    var email = await _userManager.GetEmailAsync(user);

                    await observer.Observe(async() => await _userManager.AddEmailAsync(currentUser, email));
                }

                var existingClaims = await _userManager.GetClaimsAsync(currentUser);

                var missingClaims = claims.Where(c =>
                                                 !existingClaims.Any(ec =>
                                                                     c.Type.Equals(ec.Type, StringComparison.InvariantCultureIgnoreCase) &&
                                                                     c.Value.Equals(ec.Value, StringComparison.InvariantCultureIgnoreCase)
                                                                     ));
                await observer.Observe(async() => await _userManager.AddClaimsAsync(currentUser, missingClaims));

                await observer.Observe(async() => await _userManager.DeleteAsync(user));

                await _mergeUserEvents.MergeUser(currentUser, user);

                transaction.Complete();
            }
        }