Exemple #1
0
        public async Task <ActionResult> PersistLogin([FromQuery] LoginWithPersistDTO loginWithPersistDTO)
        {
            var user = await GetUserFromContext();

            if (user == null)
            {
                return(RedirectToAction(nameof(RedirectToLogin)));
            }

            loginWithPersistDTO.SecurityKeyHash = CryptographyUtils.Base64Decode(HttpUtility.UrlDecode(loginWithPersistDTO.SecurityKeyHash));

            if (!(await PersistentRedirectUrlExist(loginWithPersistDTO.returnUrl)))
            {
                return(BadRequest("returnUrl no es un valor valido"));
            }
            var token = await userManager.GenerateUserTokenAsync(user, ApplicationConstants.AuthCodeTokenProviderName, ApplicationConstants.PersistentLoginTokenPurposeName);

            var authenticationCode = new UserAuthenticationCode
            {
                Expiration  = DateTime.UtcNow.AddMinutes(5),
                SecurityKey = loginWithPersistDTO.SecurityKeyHash,
                Token       = token,
                UserId      = user.Id
            };

            applicationDbContext.Add(authenticationCode);

            await applicationDbContext.SaveChangesAsync();


            string url = $"{loginWithPersistDTO.returnUrl}?authcode={HttpUtility.UrlEncode(token)}";

            if (!string.IsNullOrEmpty(loginWithPersistDTO.InternalUrl))
            {
                url += $"&internalUrl={HttpUtility.UrlEncode(loginWithPersistDTO.InternalUrl)}";
            }

            return(Redirect(url));
        }
Exemple #2
0
        public async Task <ActionResult> ExternalLoginCallback([FromQuery] string returnUrl)
        {
            var info = await signInManager.GetExternalLoginInfoAsync();

            bool containsIdCookie      = HttpContext.Request.Cookies.ContainsKey(ApplicationConstants.IdCookieName);
            bool containsKeyHashCookie = HttpContext.Request.Cookies.ContainsKey(ApplicationConstants.KeyHashCookieName);
            bool containsVerifierId    = HttpContext.Request.Cookies.ContainsKey(ApplicationConstants.IdCookieVerifier);

            if (info == null || (!containsKeyHashCookie && !containsIdCookie))
            {
                return(Redirect($"{ApplicationConstants.LoginFrontendDefaultEndpoint}?msg=La session ha expirado por favor intentalo de nuevo"));
            }


            var loginExist = await applicationDbContext.UserLogins.AnyAsync(l => l.ProviderKey == info.ProviderKey);

            if (loginExist && containsIdCookie && containsVerifierId)
            {
                return(Redirect($"{ApplicationConstants.ProfileFrontendDefaultEndpoint}?msg=Error! El Proveedor de identidad ya esta siendo utilizado por otro usuario"));
            }


            string keyHash = containsKeyHashCookie? HttpContext.Request.Cookies[ApplicationConstants.KeyHashCookieName]:string.Empty;


            var result = !string.IsNullOrEmpty(keyHash) && loginExist ? (await signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, false)):null;

            if (result != null && result.Succeeded)
            {
                var userIdentifier = info.Principal.FindFirst(ClaimTypes.NameIdentifier);
                if (userIdentifier == null)
                {
                    return(Redirect($"{ApplicationConstants.LoginFrontendDefaultEndpoint}?msg=Ha ocurrido un error inesperado"));
                }


                var user = await userManager.FindByLoginAsync(info.LoginProvider, userIdentifier.Value);


                var token = await userManager.GenerateUserTokenAsync(user, ApplicationConstants.AuthCodeTokenProviderName, ApplicationConstants.ExternalLoginTokenPurposeName);


                var authenticationCode = new UserAuthenticationCode
                {
                    Expiration  = DateTime.UtcNow.AddMinutes(5),
                    SecurityKey = keyHash,
                    Token       = token,
                    UserId      = user.Id
                };

                applicationDbContext.Add(authenticationCode);
                await applicationDbContext.SaveChangesAsync();

                string url = $"{returnUrl}?authcode={HttpUtility.UrlEncode(token)}";

                return(Redirect(url));
            }
            else if (result != null && result.IsNotAllowed)
            {
                return(Redirect($"{ApplicationConstants.LoginFrontendDefaultEndpoint}?msg=Tu cuenta no se encuentra activa aun, por favor verifica tu email"));
            }
            else if (result != null && result.IsLockedOut)
            {
                return(Redirect($"{ApplicationConstants.LoginFrontendDefaultEndpoint}?msg=Tu cuenta se encuentra bloqueada temporalmente intentalo de nuevo mas tarde"));
            }
            else
            {
                if (loginExist)
                {
                    return(Redirect($"{ApplicationConstants.LoginFrontendDefaultEndpoint}?msg=Proveedor de identidad ya utilizado"));
                }


                if (containsIdCookie && containsVerifierId)
                {
                    string userId = HttpContext.Request.Cookies[ApplicationConstants.IdCookieName];
                    string token  = HttpContext.Request.Cookies[ApplicationConstants.IdCookieVerifier];

                    HttpContext.Response.Cookies.Append(ApplicationConstants.IdCookieName, "", new CookieOptions
                    {
                        Expires = DateTime.Now.AddDays(-1)
                    });

                    HttpContext.Response.Cookies.Append(ApplicationConstants.IdCookieVerifier, "", new CookieOptions
                    {
                        Expires = DateTime.Now.AddDays(-1)
                    });


                    bool alreadyHaveProvider = await applicationDbContext.UserLogins.AnyAsync(y => y.ProviderDisplayName == info.ProviderDisplayName && y.UserId == userId);

                    if (alreadyHaveProvider)
                    {
                        return(Redirect($"{ApplicationConstants.ProfileFrontendDefaultEndpoint}?msg=Ya tienes ese proveedor enlazado con tu cuenta!"));
                    }

                    var currentUser = await applicationDbContext.Users.FirstOrDefaultAsync(u => u.Id == userId);

                    if (currentUser != null)
                    {
                        var tokenResult = await userManager.VerifyUserTokenAsync(currentUser, ApplicationConstants.AuthCodeTokenProviderName, userId, token);

                        if (!tokenResult)
                        {
                            return(Redirect($"{ApplicationConstants.ProfileFrontendDefaultEndpoint}?msg=Ha ocurrido un error enlazando el metodo de autenticacion intentalo mas tarde"));
                        }

                        var externLoginAddResult = await userManager.AddLoginAsync(currentUser, info);

                        if (externLoginAddResult.Succeeded)
                        {
                            return(Redirect($"{ApplicationConstants.ProfileFrontendDefaultEndpoint}?msg=Has enlazado tu cuenta exitosamente"));
                        }
                        else
                        {
                            return(Redirect($"{ApplicationConstants.ProfileFrontendDefaultEndpoint}?msg=Ha ocurrido un error enlazando el metodo de autenticacion intentalo mas tarde"));
                        }
                    }
                }
                //Register
                var email = info.Principal.FindFirst(ClaimTypes.Email);
                if (email == null)
                {
                    return(Redirect($"{ApplicationConstants.LoginFrontendDefaultEndpoint}?msg=El proveedor de identidad no envio la informacion necesaria intentalo de nuevo"));
                }



                var user = await userManager.FindByEmailAsync(email.Value);

                if (user != null)
                {
                    return(Redirect($"{ApplicationConstants.LoginFrontendDefaultEndpoint}?msg=Un usuario con ese email ya esta registrado por favor inicia session y enlaza este metodo de autenticacion"));
                }
                string name;
                var    username = info.Principal.FindFirst(ClaimTypes.Name);
                if (username == null)
                {
                    return(Redirect($"{ApplicationConstants.LoginFrontendDefaultEndpoint}?msg=El proveedor de identidad no envio la informacion necesaria intentalo de nuevo"));
                }

                name = username.Value.Replace(" ", "_");

                user = await userManager.FindByNameAsync(name);

                if (user != null)
                {
                    //Si el nombre de usuario ya existe le agregamos un numero aleatorio al final probablemente sea conveniente hacer un endpoint intermedio para preguntarle al usuario que username quiere
                    name += threadSafeRandom.Next(1, 20000).ToString();
                }


                var nUser = new ApplicationUser
                {
                    UserName = name,
                    Email    = email.Value
                };

                var creationResult = await userManager.CreateAsync(nUser);


                if (creationResult.Succeeded)
                {
                    var extLoginAdditionResult = await userManager.AddLoginAsync(nUser, info);

                    if (!extLoginAdditionResult.Succeeded)
                    {
                        return(Redirect($"{ApplicationConstants.LoginFrontendDefaultEndpoint}?msg=Ha ocurrido un error inesperado"));
                    }

                    await SendEmailConfirmation(nUser);

                    return(await ExternalLoginCallback(returnUrl));
                }
            }

            return(Redirect($"{ApplicationConstants.LoginFrontendDefaultEndpoint}?msg=Ha ocurrido un error inesperado"));
        }