.NET Core Identity Server 4 Autenticación VS Autenticación de identidad


92

Estoy tratando de comprender la forma correcta de realizar la autenticación en ASP.NET Core. He examinado varios recursos (la mayoría de los cuales están desactualizados).

Algunas personas brindan soluciones alternativas indicando que deben usar una solución basada en la nube como Azure AD, o usar IdentityServer4 y alojar mi propio Token Server.

En la versión anterior de .Net, una de las formas más simples de autenticación sería crear un principio personalizado y almacenar datos de autenticación adicionales en su interior.

public interface ICustomPrincipal : System.Security.Principal.IPrincipal
{
    string FirstName { get; set; }

    string LastName { get; set; }
}

public class CustomPrincipal : ICustomPrincipal
{
    public IIdentity Identity { get; private set; }

    public CustomPrincipal(string username)
    {
        this.Identity = new GenericIdentity(username);
    }

    public bool IsInRole(string role)
    {
        return Identity != null && Identity.IsAuthenticated && 
           !string.IsNullOrWhiteSpace(role) && Roles.IsUserInRole(Identity.Name, role);
    }

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public string FullName { get { return FirstName + " " + LastName; } }
}

public class CustomPrincipalSerializedModel
{
    public int Id { get; set; }

    public string FirstName { get; set; }

    public string LastName { get; set; }
}

Luego, serializaría sus datos en una cookie y se los devolvería al cliente.

public void CreateAuthenticationTicket(string username) {     

    var authUser = Repository.Find(u => u.Username == username);  
    CustomPrincipalSerializedModel serializeModel = new CustomPrincipalSerializedModel();

    serializeModel.FirstName = authUser.FirstName;
    serializeModel.LastName = authUser.LastName;
    JavaScriptSerializer serializer = new JavaScriptSerializer();
    string userData = serializer.Serialize(serializeModel);

    FormsAuthenticationTicket authTicket = new FormsAuthenticationTicket(
    1,username,DateTime.Now,DateTime.Now.AddHours(8),false,userData);
    string encTicket = FormsAuthentication.Encrypt(authTicket);
    HttpCookie faCookie = new HttpCookie(FormsAuthentication.FormsCookieName, encTicket);
    Response.Cookies.Add(faCookie);
}

Mis preguntas son:

  1. ¿Cómo puedo autenticarme de manera similar a la forma en que se realizaba en versiones anteriores de .Net si la forma anterior todavía funciona o hay una versión más nueva?

  2. ¿Cuáles son los pros y los contras de usar sus propios versículos de servidor de tokens para crear su propio principio personalizado?

  3. Cuando use una solución basada en la nube o un servidor Token separado, ¿cómo lo integraría con su aplicación actual? ¿Todavía necesitaría una tabla de usuarios en mi aplicación? ¿Cómo asociaría los dos?

  4. Dado que hay tantas soluciones diferentes, ¿cómo puedo crear una aplicación empresarial para permitir el inicio de sesión a través de Gmail / Facebook y al mismo tiempo poder expandirme a otros SSO?

  5. ¿Cuáles son algunas implementaciones simples de estas tecnologías?

Esta pregunta es demasiado amplia y también está muy basada en opiniones. Hay demasiadas respuestas posibles o las buenas respuestas serían demasiado largas para este formato. Agregue detalles para limitar el conjunto de respuestas o para aislar un problema que se pueda responder en unos pocos párrafos. Muchas buenas preguntas generan cierto grado de opinión basada en la experiencia de los expertos, pero las respuestas a esta pregunta tenderán a basarse casi por completo en opiniones, en lugar de hechos, referencias o conocimientos específicos.
Nkosi

@Nkosi lo siento, la frase fue así. Aclaré esto para ser más específico
johnny 5

Respuestas:


145

TL; DR

IdentityServer = servicios de validación y cifrado de tokens a través de OAuth 2.0 / OpenId-Connect

ASP.NET Identity = estrategia actual de gestión de identidades en ASP.NET

¿Cómo puedo autenticarme de manera similar a la forma en que se realizaba en versiones anteriores de .Net si la forma anterior todavía funciona o hay una versión más nueva?

No veo ninguna razón por la que no pueda lograr la forma anterior en ASP.NET Core, pero en general, esa estrategia fue reemplazada por ASP.NET Identity, y ASP.NET Identity está viva y bien en ASP.NET Core.

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/identity

ASP.NET Identity utiliza un almacén de respaldo como SQL Server para almacenar información del usuario como nombre de usuario, contraseña (hash), correo electrónico, teléfono y se puede extender fácilmente para contener Nombre, Apellido o cualquier otra cosa. Entonces, realmente no hay razón para encriptar la información del usuario en una cookie y pasarla de un cliente a otro. Admite nociones como reclamos de usuario, tokens de usuario, roles de usuario e inicios de sesión externos. Aquí están las entidades en ASP.NET Identity:

  • AspNetUsers
  • AspNetUserRoles
  • AspNetUserClaims
  • AspNetUserLogins (para vincular proveedores de identidad externos, como Google, AAD)
  • AspNetUserTokens (para almacenar cosas como access_tokens y refresh_tokens acumulados por el usuario)

¿Cuáles son los pros y los contras de usar sus propios versículos de servidor de tokens para crear su propio principio personalizado?

Un servidor de tokens sería un sistema que genera una estructura de datos simple que contiene información de autorización y / o autenticación. La autorización generalmente toma el nombre de un token llamado access_token . Estas serían las "llaves de la casa", por así decirlo, que le permitirán atravesar la puerta y entrar en la residencia de un recurso protegido, generalmente una API web. Para la autenticación, id_tokencontiene un identificador único para un usuario / persona. Si bien es común poner un identificador de este tipo en el access_token, ahora existe un protocolo dedicado para hacerlo: OpenID-Connect .

La razón para tener su propio Security Token Service (STS) sería proteger sus activos de información, a través de criptografía, y controlar qué clientes (aplicaciones) pueden acceder a esos recursos. Además, los estándares para los controles de identidad ahora existen en las especificaciones OpenID-Connect. IdentityServer es un ejemplo de un servidor de autorización OAuth 2.0 combinado con un servidor de autenticación OpenID-Connect.

Pero nada de esto es necesario si solo desea una tabla de usuario en su aplicación. No necesita un servidor de tokens, solo use ASP.NET Identity. ASP.NET Identity asigna su usuario a un objeto ClaimsIdentity en el servidor, sin necesidad de una clase IPrincipal personalizada.

Cuando use una solución basada en la nube o un servidor Token separado, ¿cómo lo integraría con su aplicación actual? ¿Todavía necesitaría una tabla de usuarios en mi aplicación? ¿Cómo asociaría los dos?

Consulte estos tutoriales para integrar soluciones de identidad independientes con una aplicación: https://identityserver4.readthedocs.io/en/latest/quickstarts/0_overview.html https://auth0.com/docs/quickstart/webapp/aspnet-core

Como mínimo, necesitará una tabla de dos columnas que asigne el nombre de usuario al identificador de usuario del proveedor externo. Esto es lo que hace la tabla AspNetUserLogins en ASP.NET Identity. Sin embargo, las filas de esa tabla dependen de que sea un registro de usuario en AspNetUsers.

ASP.NET Identity admite proveedores externos como Google, Microsoft, Facebook, cualquier proveedor de OpenID-Connect, Azure AD ya están allí. (Google y Microsoft ya han implementado el protocolo OpenID-Connect, por lo que tampoco necesita sus paquetes de integración personalizados, como este , por ejemplo). Además, ADFS aún no está disponible en ASP.NET Core Identity.

Consulte este documento para comenzar con proveedores externos en ASP.NET Identity:

https://docs.microsoft.com/en-us/aspnet/core/security/authentication/social/

Dado que hay tantas soluciones diferentes, ¿cómo puedo crear una aplicación empresarial para permitir el inicio de sesión a través de Gmail / Facebook y al mismo tiempo poder expandirme a otros SSO?

Como se explicó anteriormente, ASP.NET Identity ya hace esto. Es bastante fácil crear una tabla de "Proveedores externos" y los datos controlan su proceso de inicio de sesión externo. Entonces, cuando aparece un nuevo "SSO", simplemente agregue una nueva fila con las propiedades como la URL del proveedor, la identificación del cliente y el secreto que le brindan. ASP.NET Identity ya tiene la interfaz de usuario integrada en las plantillas de Visual Studio, pero consulte Inicio de sesión social para conocer los botones más interesantes.

Resumen

Si solo necesita una tabla de usuarios con capacidades de inicio de sesión con contraseña y un perfil de usuario, entonces ASP.NET Identity es perfecto. No es necesario involucrar a autoridades externas. Pero, si tiene muchas aplicaciones que necesitan acceder a muchas apis, entonces una autoridad independiente para asegurar y validar tokens de identidad y acceso tiene sentido. IdentityServer es una buena opción , o vea openiddict-core o Auth0 para una solución en la nube.

Mis disculpas es que esto no está dando en el blanco o si es demasiado introductorio. No dude en interactuar para llegar a la diana que está buscando.

Anexo: autenticación de cookies

Para realizar una autenticación básica con cookies, siga estos pasos. Pero, que yo sepa, no se admite una entidad de seguridad personalizada. Para lograr el mismo efecto, utilice la lista de Reclamaciones del ClaimPrincipalobjeto.

Cree una nueva aplicación web ASP.NET Core 1.1 en Visual Studio 2015/2017 eligiendo "Sin autenticación" en el cuadro de diálogo. Luego agregue el paquete:

Microsoft.AspNetCore.Authentication.Cookies

Bajo el Configuremétodo Startup.csimplementado esto (antes app.UseMvc):

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationScheme = "MyCookieMiddlewareInstance",
    LoginPath = new PathString("/Controller/Login/"),
    AutomaticAuthenticate = true,
    AutomaticChallenge = true
});

Luego, cree una interfaz de usuario de inicio de sesión y publique el formulario html en un método de acción como este:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Login(String username, String password, String returnUrl = null)
{
    ViewData["ReturnUrl"] = returnUrl;
    if (ModelState.IsValid)
    {
        // check user's password hash in database
        // retrieve user info

        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, username),
            new Claim("FirstName", "Alice"),
            new Claim("LastName", "Smith")
        };

        var identity = new ClaimsIdentity(claims, "Password");

        var principal = new ClaimsPrincipal(identity);

        await HttpContext.Authentication.SignInAsync("MyCookieMiddlewareInstance", principal);

        return RedirectToLocal(returnUrl);
    }

    ModelState.AddModelError(String.Empty, "Invalid login attempt.");

    return View();
}

El objeto HttpContext.User debe tener sus reclamos personalizados y se puede recuperar fácilmente la colección List de ClaimPrincipal.

Espero que esto sea suficiente, ya que una Solución / Proyecto completo parece demasiado para una publicación de StackOverflow.


1
Muestre un ejemplo de implementación de autenticación en el núcleo
johnny 5

2
Los documentos de ASP.NET Core muestran el ejemplo canónico: docs.microsoft.com/en-us/aspnet/core/security/authentication/… .
travis.js

Si puede, publique un ejemplo sencillo de autenticación. Sin un enlace para que las personas tengan un recurso al que acceder, publicaré una respuesta detallada sobre cómo configurar IdentityServer4
johnny 5

Para IdentityServer, ¿tiene el ejemplo que busca: identityserver4.readthedocs.io/en/dev/quickstarts/… ?
travis.js

Para ASP.NET Identity, ¿no tiene el ejemplo o es que lo que está diciendo no está actualizado? docs.microsoft.com/en-us/aspnet/core/security/authentication/…
travis.js

11

TL; DR

Realmente me gustaría mostrar una publicación completa sobre cómo implementar correctamente IdentityServer4, pero traté de encajar todo el texto, pero estaba más allá del límite de lo que StackOverflow acepta, así que en su lugar corregiré algunos consejos y cosas que he aprendido.

¿Cuáles son los beneficios de utilizar una identidad de servidor de token frente a ASP?

Un servidor de tokens tiene muchos beneficios, pero no es adecuado para todos. Si está implementando una solución empresarial, donde desea que varios clientes puedan iniciar sesión, el servidor Token es su mejor opción, pero si solo está creando un sitio web simple que desea admitir inicios de sesión externos, puede salir adelante con ASP Identity y algo de Middleware.

Consejos de Identity Server 4

El servidor de identidad 4 está bastante bien documentado en comparación con muchos otros marcos que he visto, pero es difícil comenzar desde cero y ver el panorama completo.

Mi primer error fue intentar usar OAuth como autenticación, sí, hay formas de hacerlo, pero OAuth es para autorización, no autenticación, si desea autenticarse, use OpenIdConnect (OIDC)

En mi caso, quería crear un cliente javascript, que se conecta a una api web. Miré muchas de las soluciones, pero inicialmente traté de usar el webapi para llamar a Authenticate contra Identity Server y solo iba a hacer que ese token persistiera porque se verificó contra el servidor. Ese flujo puede funcionar potencialmente, pero tiene muchos defectos.

Finalmente, el flujo adecuado cuando encontré la muestra del cliente Javascript obtuve el flujo correcto. Su Cliente inicia sesión y establece un token. Luego, su api web consume el cliente OIdc, que verificará su token de acceso contra IdentityServer.

Conexión con tiendas y migraciones Al principio, tenía muchos conceptos erróneos sobre las migraciones. Tenía la impresión de que ejecutar una migración generó el SQL desde el dll internamente, en lugar de usar el contexto configurado para descubrir cómo crear el SQL.

Existen dos sintaxis para las migraciones, saber cuál usa su computadora es importante:

dotnet ef migrations add InitialIdentityServerMigration -c ApplicationDbContext

Add-Migration InitialIdentityServerDbMigration -c ApplicationDbContext

Creo que el parámetro después de la migración es el nombre, no estoy seguro de por qué necesita un nombre, ApplicationDbContextes un DbContext Code-First en el que desea crear.

Las migraciones usan algo de magia automática para encontrar su cadena de conexión de cómo está configurada su inicio, simplemente asumí que usaba una conexión del Explorador de servidores.

Si tiene varios proyectos, asegúrese de tener el proyecto con ApplicationDbContext configurado como inicio.

Hay muchas partes móviles al implementar la autorización y la autenticación. Con suerte, esta publicación ayudará a alguien. La forma más fácil de comprender completamente las autenticaciones es separar sus ejemplos para unir todo y asegurarse de leer la documentación.


el nombre después de agregar-migración es la referencia relacionada con su lanzamiento / cambios que realizó. Se usará el mismo nombre para agregar el script de migración hacia arriba y hacia abajo.
Jay

@Jay Gracias por esa aclaración
johnny 5

El contexto de la base de datos de configuración del servidor de identidad todavía no es tan bueno como IdentityDbContext. la creación de una implementación personalizada es una molestia. Identityserver 4 ahora parece no estar muy activo para lanzar nuevas actualizaciones después de las actualizaciones .core.
Jay

3

Identidad ASP.NET: esta es la compilación de una manera de autenticar su aplicación, ya sea portador o autenticación básica, nos brinda el código listo para realizar el registro de usuario, inicio de sesión, cambio de contraseña y todo.

Ahora considere que tenemos 10 aplicaciones diferentes y no es factible hacer lo mismo en las 10 aplicaciones. esa muy frágil y muy mala práctica.

Para resolver este problema, lo que podemos hacer es centralizar nuestra Autenticación y autorización para que cada cambio con esto no afecte a nuestras 10 aplicaciones.

El servidor de identidad le ofrece la posibilidad de hacer lo mismo. Podemos crear una aplicación web de muestra que se acaba de utilizar como servicio de identidad y validará a su usuario y le proporcionará un token de acceso JWT.


2

Siempre he usado la autorización / autenticación de identidad ASP.NET incorporada (y anteriormente Membresía), he implementado Auth0 recientemente ( https://auth0.com ) y recomiendo esto como algo más para probar.


El ejemplo principal de Auth0 .net es bastante rápido y simple de implementar, pero usar todas las funciones requiere un poco de trabajo, he implementado Auth0 integrando muchas funciones y funciona bien, pero como todas estas cosas, sus necesidades son un poco de trabajo y algo de frustración.
Mark Redman

Cuando consiga que una autenticación funcione bien, publicaré una respuesta detallada al respecto. Estuve trabajando en la autenticación la semana pasada. Y nada es tan directo como debería ser
johnny 5

0

Los inicios de sesión sociales no son difíciles de implementar con Identity, pero hay una configuración inicial involucrada y, a veces, los pasos que encuentra en línea en los documentos no son idénticos, por lo general, puede encontrar ayuda para eso en la sección de desarrolladores de la plataforma que está tratando de configurar. los inicios de sesión sociales para. La identidad es el reemplazo de la antigua funcionalidad de membresía que se encuentra en las versiones heredadas del marco .net Lo que me sorprendió es que los casos de uso de borde, como pasar un token jwt que ya tiene a una API web, no se tratan en ningún lugar de los ejemplos en línea incluso en pluralsight, estoy seguro de que no necesita su propia autoridad de token para hacer esto, pero no he encontrado un solo ejemplo sobre cómo pasar datos en un get o post que no se trate de un servidor autohospedado.


tal vez estés después de este docs.identityserver.io/en/release/quickstarts/…
Jay
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.