public ActionResult ExternalLogOn(string returnUrl) { AuthenticationResult result = _orchardOpenAuthWebSecurity.VerifyAuthentication(Url.OpenAuthLogOn(returnUrl)); if (!result.IsSuccessful) { _notifier.Error(T("Your authentication request failed.")); return(new RedirectResult(Url.LogOn(returnUrl))); } if (_orchardOpenAuthWebSecurity.Login(result.Provider, result.ProviderUserId)) { _notifier.Information(T("You have been logged using your {0} account.", result.Provider)); return(this.RedirectLocal(returnUrl)); } var authenticatedUser = _authenticationService.GetAuthenticatedUser(); if (authenticatedUser != null) { // If the current user is logged in add the new account _orchardOpenAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, authenticatedUser); _notifier.Information(T("Your {0} account has been attached to your local account.", result.Provider)); return(this.RedirectLocal(returnUrl)); } if (_openAuthMembershipServices.CanRegister()) { var newUser = _openAuthMembershipServices.CreateUser(new OpenAuthCreateUserParams(result.UserName, result.Provider, result.ProviderUserId, result.ExtraData)); _notifier.Information( T("You have been logged in using your {0} account. We have created a local account for you with the name '{1}'", result.Provider, newUser.UserName)); _orchardOpenAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, newUser); _authenticationService.SignIn(newUser, false); return(this.RedirectLocal(returnUrl)); } string loginData = _orchardOpenAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId); ViewBag.ProviderDisplayName = _orchardOpenAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName; ViewBag.ReturnUrl = returnUrl; return(new RedirectResult(Url.LogOn(returnUrl, result.UserName, HttpUtility.UrlEncode(loginData)))); }
private void UserMergeAndSignIn( IUser masterUser, AuthenticationResult result, string returnUrl, bool createPersistentCookie = false) { // If the current user is logged in or settings ask for a user merge and we found a User with the same email // create or merge accounts _orchardOpenAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, masterUser, result.ExtraData); _notifier.Information(T("Your {0} account has been attached to your local account.", result.Provider)); // Handle LoggedIn Event var authenticatedUser = _authenticationService.GetAuthenticatedUser(); if (authenticatedUser == null) { _authenticationService.SignIn(masterUser, createPersistentCookie); _userEventHandler.LoggedIn(masterUser); // The LoggedIn event is invoked here, because if authenticateUser != null, then it means the user // had already logged in some other time } }
private void CreateOrUpdateOpenAuthUser(IUser user) { var current = _httpContextAccessor.Current(); if (current == null) { return; } var request = current.Request; if (request == null) { return; } var userName = request.QueryString["UserName"]; var externalLoginData = request.QueryString["ExternalLoginData"]; if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(externalLoginData)) { return; } string providerName; string providerUserId; if ( !_orchardOpenAuthWebSecurity.TryDeserializeProviderUserId(externalLoginData, out providerName, out providerUserId)) { return; } _orchardOpenAuthWebSecurity.CreateOrUpdateAccount(providerName, providerUserId, user); }
public ActionResult ExternalLogOn(string returnUrl, bool createPersistentCookie = false) { AuthenticationResult result = _orchardOpenAuthWebSecurity.VerifyAuthentication(Url.OpenAuthLogOn(returnUrl)); if (!result.IsSuccessful) { _notifier.Error(T("Your authentication request failed.")); return(new RedirectResult(Url.LogOn(returnUrl))); } if (_orchardOpenAuthWebSecurity.Login(result.Provider, result.ProviderUserId)) { _notifier.Information(T("You have been logged using your {0} account.", result.Provider)); return(this.RedirectLocal(returnUrl)); } // At this point, login using the OpenAuth provider failed, meaning that we could not find a match // between the information from the provider and Orchard's users. // Get additional UserData if (result.ExtraData.ContainsKey("accesstoken")) { result = _openAuthClientProvider.GetUserData(result.Provider, result, result.ExtraData["accesstoken"]); } else { result = _openAuthClientProvider.GetUserData(result.Provider, result, ""); } // _openAuthClientProvider.GetUserData(params) may return null if there is no configuration for a provider // with the given name. if (result == null) { // handle this condition and exit the method _notifier.Error(T("Your authentication request failed.")); return(new RedirectResult(Url.LogOn(returnUrl))); } // _openAuthClientProvider.NormalizeData(params) may return null if there is no configuration for a provider // with the given name. If result != null, that is not the case, because in that condition GetUserData(params) // would return null, and we would have already exited the method. var userParams = _openAuthClientProvider.NormalizeData(result.Provider, new OpenAuthCreateUserParams(result.UserName, result.Provider, result.ProviderUserId, result.ExtraData)); var temporaryUser = _openAuthMembershipServices.CreateTemporaryUser(userParams); // In what condition can GetAuthenticatedUser() not be null? To reach this code, _orchardOpenAuthWebSecurity.Login(params) // must have returned false. That happens if there was no record for the combination Provider/ProviderUserId, or if // GetAuthenticatedUser() returned null in it. In the latter case, it should still return null. The former case means // we are trying to login with an OAuth provider and it's the first time we are calling it for this user, but we are // also already authenticated in some other way. This only makes sense in a situation where, as authenticated users, // we are allowed to add information from OAuth providers to our account: Users/Account/LogOn, if the user is authenticated, // redirects to the homepage, and does not give an option to go and login again using OAuth. var masterUser = _authenticationService.GetAuthenticatedUser() ?? _orchardOpenAuthWebSecurity.GetClosestMergeableKnownUser(temporaryUser); // The authenticated User or depending from settings the first created user with the same e-mail if (masterUser != null) { // If the current user is logged in or settings ask for a user merge and we found a User with the same email // create or merge accounts _orchardOpenAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, masterUser, result.ExtraData); _notifier.Information(T("Your {0} account has been attached to your local account.", result.Provider)); if (_authenticationService.GetAuthenticatedUser() != null) // if the user was already logged in // here masterUser == _authenticationService.GetAuthenticatedUser() { return(this.RedirectLocal(returnUrl)); } } if (_openAuthMembershipServices.CanRegister() && masterUser == null) { // User can register and there is not a user with the same email var createUserParams = new OpenAuthCreateUserParams(result.UserName, result.Provider, result.ProviderUserId, result.ExtraData); createUserParams = _openAuthClientProvider.NormalizeData(result.Provider, createUserParams); // Creating the user here calls the IMembershipService, that will take care of invoking the user events var newUser = _openAuthMembershipServices.CreateUser(createUserParams); // newUser may be null here, if creation of a new user fails. // TODO: we should elsewhere add an UserEventHandler that in the Creating event handles the case where // here we are trying to create a user with the same Username or Email as an existing one. That would simply // use IUserService.VerifyUnicity(username, email). However this may break things for our older tenants. if (newUser != null) { // CreateOrUpdateAccount causes specific OpenAuth events to fire _orchardOpenAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, newUser, result.ExtraData); // The default implementation of IOpendAuthMembershipService creates an approved user. // The events specific to open auth give points to attach handlers where the UserProviderRecord // is populated correctly. // We created the user and are going to sign them in, so we should fire off the related events. // We cannot really invoke the LoggingIn event, because we do not have the password, but we can invoke // the LoggedIn event later. _authenticationService.SignIn(newUser, createPersistentCookie); _notifier.Information( T("You have been logged in using your {0} account. We have created a local account for you with the name '{1}'", result.Provider, newUser.UserName)); _userEventHandler.LoggedIn(newUser); } else { _notifier.Error(T("Your authentication request failed.")); } return(this.RedirectLocal(returnUrl)); } else if (masterUser != null) { _authenticationService.SignIn(masterUser, createPersistentCookie); _userEventHandler.LoggedIn(masterUser); _notifier.Information(T("You have been logged in using your {0} account.", result.Provider)); return(this.RedirectLocal(returnUrl)); } // We are in the case which we cannot creates new accounts, we have no user to merge, the user is not logged in // so we ask to user to login to merge accounts string loginData = _orchardOpenAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId); ViewBag.ProviderDisplayName = _orchardOpenAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName; ViewBag.ReturnUrl = returnUrl; // the LogOn Helper here is not doing any validaiton on the stuff it's putting in query string, so it // may end up having forbidden character sequences. return(new RedirectResult(Url.LogOn(returnUrl, result.UserName, loginData))); }