TL; DR you need to go through all the scripts manually in your ExternalLoginConfirmation function and have a database table in order to be able to map the user ID to the OAuth user ID. This way you can βlinkβ multiple OAuth accounts to one local account.
Below is a snippet of code from one of our projects - I hope it is clear enough
public ActionResult ExternalLoginCallback() { var returnUrl = HttpContext.Request.QueryString["returnUrl"]; var result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl })); if (result.IsSuccessful == false) { return this.View("ExternalLoginFailure", result); } // Login user if provider represents a valid already registered user if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false)) { return this.RedirectToLocal(returnUrl); } // If the current user is logged in already - add new account if (User.Identity.IsAuthenticated) { OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name); return this.RedirectToLocal(returnUrl); } var membershipUser = Membership.GetUser(result.UserName); // so user is new - then create new membership account if (membershipUser == null) { MembershipCreateStatus createStatus; membershipUser = Membership.CreateUser(username: result.UserName, password: this.GetTempPassword(), email: result.UserName, status: out createStatus); if (createStatus == MembershipCreateStatus.Success) { this.emailService.SendWelcome(this, (Guid)membershipUser.ProviderUserKey); // Associate social network account with created membership account OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, result.UserName); OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false); return this.RedirectToLocal(returnUrl); } // The problem occured while creating membership account this.ViewBag.Error = MembershipErrorNameProvider.FromErrorCode(createStatus); return this.View("CreateMembershipAccountFailure"); } // If membership account already exists -> Associate Social network account with exists membership account OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, result.UserName); OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false); return this.RedirectToLocal(returnUrl); }
and OAuthWebSecurity is a helper class that applies to all the providers you support:
public static class OAuthWebSecurity { .... public static bool Login(string providerName, string providerUserId, bool createPersistentCookie) { var context = new HttpContextWrapper(HttpContext.Current); var provider = GetOAuthClient(providerName); var securityManager = new OpenAuthSecurityManager(context, provider, OAuthDataProvider); return securityManager.Login(providerUserId, createPersistentCookie); } public static void CreateOrUpdateAccount(string openAuthProvider, string openAuthId, string userName) { var user = UserRepository.FindByName(userName); if (user == null) { throw new MembershipUserNotFoundException(); } var userOAuthAccount = UserOAuthAccountRepository.Find(openAuthProvider, openAuthId); if (userOAuthAccount == null) { UserOAuthAccountRepository.InsertOrUpdate(new UserOAuthAccount { OAuthProvider = openAuthProvider, OAuthId = openAuthId, UserId = user.Id }); } else { userOAuthAccount.UserId = user.Id; } UserOAuthAccountRepository.Save(); } }
avs099
source share