Saltar al contenido

cómo implementar el inicio de sesión de Google en .net core sin un proveedor de entityframework

Después de de esta prolongada selección de información pudimos solucionar esta cuestión que tienen ciertos usuarios. Te regalamos la respuesta y deseamos que resulte de gran apoyo.

Solución:

Si todo lo que quiere hacer es iniciar sesión con Google, no es necesario SignInManager, UserManager o la propia identidad de ASP.NET Core. Para lograr esto, primero necesitamos configurar los servicios de Autenticación. Aquí está el código relevante para esto, que explicaré después:

Startup.cs

services
    .AddAuthentication(o =>
    
        o.DefaultScheme = "Application";
        o.DefaultSignInScheme = "External";
    )
    .AddCookie("Application")
    .AddCookie("External")
    .AddGoogle(o =>
    
        o.ClientId = ...;
        o.ClientSecret = ...;
    );
  • La llamada a AddAuthentication configura un DefaultScheme, que termina siendo utilizado tanto como el Solicitud esquema y el Desafío esquema. los Solicitud El esquema se utiliza al intentar autenticar al usuario (¿ha iniciado sesión?). los Desafío El esquema se utiliza cuando un usuario no ha iniciado sesión pero la aplicación quiere ofrecer la opción de hacerlo. Discutiré el DefaultSignInScheme más tarde.

  • Las dos llamadas a AddCookie agregue esquemas de autenticación basados ​​en cookies para ambos Application (nuestro Solicitud esquema) y External (nuestro Registrarse esquema). AddCookie también puede tomar un segundo argumento, que permite la configuración de, por ejemplo, la duración de la cookie correspondiente, etc.

Con esto en su lugar, el proceso de desafío redirigirá al usuario a /Account/Login (de forma predeterminada, esto también se puede configurar a través de las opciones de autenticación de cookies). Aquí hay una implementación de controlador que maneja el proceso de desafío (nuevamente, lo explicaré después):

AccountController.cs

public class AccountController : Controller

    public IActionResult Login(string returnUrl)
    
        return new ChallengeResult(
            GoogleDefaults.AuthenticationScheme,
            new AuthenticationProperties
            
                RedirectUri = Url.Action(nameof(LoginCallback), new  returnUrl )
            );
    

    public async Task LoginCallback(string returnUrl)
    
        var authenticateResult = await HttpContext.AuthenticateAsync("External");

        if (!authenticateResult.Succeeded)
            return BadRequest(); // TODO: Handle this better.

        var claimsIdentity = new ClaimsIdentity("Application");

        claimsIdentity.AddClaim(authenticateResult.Principal.FindFirst(ClaimTypes.NameIdentifier));
        claimsIdentity.AddClaim(authenticateResult.Principal.FindFirst(ClaimTypes.Email));

        await HttpContext.SignInAsync(
            "Application",
            new ClaimsPrincipal(claimsIdentity));

        return LocalRedirect(returnUrl);
    

Dividamos esto en dos acciones:

  1. Login

    Para llegar al Login acción, el usuario habrá sido desafiado. Esto ocurre cuando el usuario no ha iniciado sesión con el Application esquema pero está intentando acceder a una página protegida por el Authorize attribute (o similar). Según su requisito, si el usuario no ha iniciado sesión, queremos iniciar sesión con Google. Para lograrlo, emitimos un nuevo desafío, esta vez para el Google esquema. Lo hacemos usando un ChallengeResult que está configurado con el Google esquema y un RedirectUrl, que se utiliza para volver a nuestro propio código de aplicación una vez que se completa el proceso de inicio de sesión de Google. Como muestra el código, volvemos a:

  2. LoginCallback

    Aquí es donde el DefaultSignInScheme de nuestra llamada a AddAuthentication se vuelve relevante. Como parte del proceso de inicio de sesión de Google, el DefaultSignInScheme se utiliza para configurar una cookie que contiene un ClaimsPrincipal representar al usuario como devuelto por Google (todo esto se maneja detrás de escena). La primera línea de código en LoginCallback agarra esto ClaimsPrincipal instancia, que está envuelto dentro de un AuthenticateResult que primero se verifica para verificar su éxito. Si todo ha tenido éxito hasta ahora, terminamos creando un nuevo ClaimsPrincipal que contiene los reclamos que necesitamos (tomados de Google en este caso) y luego iniciar sesión en ese ClaimsPrincipal utilizando el Application esquema. Por último, redirigimos a la página que provocó nuestra primera desafío.

En respuesta a un par de comentarios / preguntas de seguimiento en los comentarios a continuación:

¿Puedo concluir que el SignInManager y UserManager sólo se utilizan cuando se utiliza la autenticación con una base de datos?

De alguna manera, sí, creo que eso es justo. Aunque es posible implementar un almacén en memoria, en realidad no tiene mucho sentido sin persistencia. Sin embargo, la verdadera razón para no usar estas clases en su situación es simplemente porque no necesita una cuenta de usuario local para representar a un usuario. Eso va de la mano con la perseverancia, pero vale la pena hacer la distinción.

Y qué código muy diferente de lo que leí en el libro (que usé para configurar mi inicio de sesión de Google) y todas las otras respuestas que he leído.

La documentación y los libros cubren el caso de uso más común, en el que hacer desea almacenar usuarios locales que pueden ser vinculado a cuentas externas como Google, etc. Si miras el SignInManager fuente, verá que en realidad está encima del tipo de código que he mostrado arriba (por ejemplo, aquí y aquí). Se puede encontrar otro código en la interfaz de usuario predeterminada (por ejemplo, aquí) y en AddIdentity.

Supongo que Google llama a LoginCallback. ¿HttpContext.AuthenticateAsync sabe cómo verificar los datos que me envía Google? Y como su nombre es tan genérico, parece que sabe cómo hacerlo para todos los proveedores externos.

La llamada a AuthenticateAsync aqui no sabe cualquier cosa acerca de Google: el manejo específico de Google se configura mediante la llamada a AddGoogle fuera de AddAuthentication en ConfigureServices. Después de redirigir a Google para iniciar sesión, volvemos a /signin-google en nuestra aplicación. Nuevamente, esto se maneja gracias a la llamada a AddGoogle, pero ese código en realidad solo emite una cookie en el External esquema que almacena los reclamos que regresaron de Google y luego redirigir a nuestro LoginCallback endpoint que configuramos. Si agrega una llamada a AddFacebook, a /sigin-facebook endpoint se configurará para hacer algo similar. La llamada a AuthenticateAsync es realmente solo rehidratar un ClaimsPrincipal a partir de la cookie que fue creada, por ejemplo, por /signin-google endpoint, para recuperar las reclamaciones.

También vale la pena señalar que el proceso de inicio de sesión de Google / Facebook se basa en el protocolo OAuth 2, por lo que es algo genérico en sí mismo. Si necesitara soporte para algo más que Google, simplemente emitiría el desafío contra el esquema requerido en lugar de codificarlo en Google como lo hice en el ejemplo. También es posible agregar propiedades adicionales al desafío para poder determinar qué proveedor se utilizó cuando su LoginCallback se alcanza el punto final.


Creé un repositorio de GitHub que contiene un ejemplo completo que construí para escribir esta respuesta aquí.

Valoraciones y comentarios

Si eres capaz, tienes la opción de dejar un enunciado acerca de qué le añadirías a este post.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *