Beispiel #1
0
        public async Task <IActionResult> RegisterUser(RegisterUserViewModel model)
        {
            if (ModelState.IsValid)
            {
                // create user + claims
                var userToCreate = new QuantusUser();
                userToCreate.Id       = Guid.NewGuid();
                userToCreate.Password = model.Password;
                userToCreate.UserName = model.Username;
                userToCreate.IsActive = true;
                userToCreate.Claims.Add(new QuantusUserClaim()
                {
                    UserId = userToCreate.Id, ClaimType = "country", ClaimValue = model.Country
                });
                userToCreate.Claims.Add(new QuantusUserClaim()
                {
                    UserId = userToCreate.Id, ClaimType = "address", ClaimValue = model.Address
                });
                userToCreate.Claims.Add(new QuantusUserClaim()
                {
                    UserId = userToCreate.Id, ClaimType = "given_name", ClaimValue = model.Firstname
                });
                userToCreate.Claims.Add(new QuantusUserClaim()
                {
                    UserId = userToCreate.Id, ClaimType = "family_name", ClaimValue = model.Lastname
                });
                userToCreate.Claims.Add(new QuantusUserClaim()
                {
                    UserId = userToCreate.Id, ClaimType = "email", ClaimValue = model.Email
                });
                userToCreate.Claims.Add(new QuantusUserClaim()
                {
                    UserId = userToCreate.Id, ClaimType = "subscriptionlevel", ClaimValue = "FreeUser"
                });

                // if we're provisioning a user via external login, we must add the provider &
                // user id at the provider to this user's logins
                if (model.IsProvisioningFromExternal)
                {
                    userToCreate.Logins.Add(new QuantusUserLogin()
                    {
                        LoginProvider = model.Provider,
                        ProviderKey   = model.ProviderUserId,
                        UserId        = userToCreate.Id
                    });
                }

                // add it through the repository
                _quantusUserRepository.AddUser(userToCreate);

                if (!_quantusUserRepository.Save())
                {
                    throw new Exception($"Creating a user failed.");
                }

                if (!model.IsProvisioningFromExternal)
                {
                    // log the user in
                    //await HttpContext.Authentication.SignInAsync(userToCreate.SubjectId, userToCreate.Username);
                    await _httpContextAccssor.HttpContext.SignInAsync(userToCreate.Id.ToString(), userToCreate.UserName);
                }

                // continue with the flow
                if (_interaction.IsValidReturnUrl(model.ReturnUrl) || Url.IsLocalUrl(model.ReturnUrl))
                {
                    return(Redirect(model.ReturnUrl));
                }

                return(Redirect("~/"));
            }

            // ModelState invalid, return the view with the passed-in model
            // so changes can be made
            return(View(model));
        }
Beispiel #2
0
        public async Task <IActionResult> ExternalLoginCallback()
        {
            // read external identity from the temporary cookie
            var result = await HttpContext.AuthenticateAsync(
                IdentityServerConstants.ExternalCookieAuthenticationScheme);

            if (result?.Succeeded != true)
            {
                throw new Exception("External authentication error");
            }

            // lookup our user and external provider info
            //var (user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);
            var(user, provider, providerUserId, claims) = FindUserFromExternalProvider(result);
            if (user == null)
            {
                // user wasn't found by provider, but maybe one exists with the same email address?
                if (provider == "Facebook")
                {
                    // email claim from Facebook
                    var email = claims.FirstOrDefault(c =>
                                                      c.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress");
                    if (email != null)
                    {
                        var userByEmail = _quantusUserRepository.GetUserByEmail(email.Value);
                        if (userByEmail != null)
                        {
                            // add Facebook as a provider for this user
                            _quantusUserRepository.AddUserLogin(userByEmail.Id, provider, providerUserId);

                            if (!_quantusUserRepository.Save())
                            {
                                throw new Exception($"Adding a login for a user failed.");
                            }

                            // redirect to ExternalLoginCallback
                            var continueWithUrlAfterAddingUserLogin =
                                Url.Action("ExternalLoginCallback");

                            return(Redirect(continueWithUrlAfterAddingUserLogin));
                        }
                        else
                        {
                            var registerModel = new RegisterUserViewModel()
                            {
                                Username       = email.Value,
                                Password       = Guid.NewGuid().ToString(),
                                Firstname      = claims.FirstOrDefault(f => f.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname").Value,
                                Lastname       = claims.FirstOrDefault(f => f.Type == "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname").Value,
                                Email          = email.Value,
                                Provider       = provider,
                                ProviderUserId = providerUserId,
                                ReturnUrl      = Url.Action("ExternalLoginCallback")
                            };

                            // TODO: THIS MUST BE TRANSFERRED COVERTLY
                            // redirect to ExternalLoginCallback
                            var continueWithUrlAfterAddingUserLogin =
                                Url.Action("RegisterUserProvisioningFromExternal", "UserRegistration", registerModel);

                            return(Redirect(continueWithUrlAfterAddingUserLogin));
                        }
                    }
                    else
                    {
                        throw new ArgumentNullException($"Email from identity provider is null or could not be parsed");
                    }
                }
                else
                {
                    //// this might be where you might initiate a custom workflow for user registration
                    //// in this sample we don't show how that would be done, as our sample implementation
                    //// simply auto-provisions new external user
                    //user = AutoProvisionUser(provider, providerUserId, claims);
                    //var returnUrlAfterRegistration =
                    //    Url.Action("ExternalLoginCallback"/*, new {returnUrl = "not need since this identity sever version!"}*/); // Not like in course!

                    var continueWithUrl = Url.Action("RegisterUser", "UserRegistration",
                                                     new { /*returnUrl = returnUrlAfterRegistration,*/ provider = provider, providerUserId = providerUserId }); // Not like in course!

                    return(Redirect(continueWithUrl));
                }
            }

            // this allows us to collect any additonal claims or properties
            // for the specific prtotocols used and store them in the local auth cookie.
            // this is typically used to store data needed for signout from those protocols.
            var additionalLocalClaims = new List <Claim>();
            var localSignInProps      = new AuthenticationProperties();

            ProcessLoginCallbackForOidc(result, additionalLocalClaims, localSignInProps);
            ProcessLoginCallbackForWsFed(result, additionalLocalClaims, localSignInProps);
            ProcessLoginCallbackForSaml2p(result, additionalLocalClaims, localSignInProps);

            // issue authentication cookie for user
            await _events.RaiseAsync(new UserLoginSuccessEvent(provider, providerUserId, user.Id.ToString(), user.UserName));

            await HttpContext.SignInAsync(user.Id.ToString(), user.UserName, provider, localSignInProps, additionalLocalClaims.ToArray());

            // delete temporary cookie used during external authentication
            await HttpContext.SignOutAsync(IdentityServer4.IdentityServerConstants.ExternalCookieAuthenticationScheme);

            // validate return URL and redirect back to authorization endpoint or a local page
            var returnUrl = result.Properties.Items["returnUrl"];

            if (_interaction.IsValidReturnUrl(returnUrl) || Url.IsLocalUrl(returnUrl))
            {
                return(Redirect(returnUrl));
            }

            return(Redirect("~/"));
        }