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); } }
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()); }
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(); } }