Saltar al contenido

¿Cómo configuro varios esquemas de autenticación en ASP.NET Core 2.0?

El paso a paso o código que hallarás en este artículo es la resolución más rápida y efectiva que encontramos a tus dudas o problema.

Solución:

Edición de diciembre de 2019: considere esta respuesta antes que cualquier otra cosa: use autenticación de portador JWT múltiple

Mi respuesta anterior (que no encaja con múltiples JWT sino solo JWT + API keycomo comentó un usuario):

Otra posibilidad es determinar en tiempo de ejecución qué esquema de política de autenticación elegir, tuve el caso en el que podría tener un encabezado de token de portador de autenticación http o una cookie.

Entonces, gracias a https://github.com/aspnet/Security/issues/1469

Token JWT si hay alguno en el encabezado de la solicitud, luego OpenIdConnect (Azure AD) o cualquier otra cosa.

public void ConfigureServices(IServiceCollection services)
    
        // Add CORS
        services.AddCors();

        // Add authentication before adding MVC
        // Add JWT and Azure AD (that uses OpenIdConnect) and cookies.
        // Use a smart policy scheme to choose the correct authentication scheme at runtime
        services
            .AddAuthentication(sharedOptions =>
            
                sharedOptions.DefaultScheme = "smart";
                sharedOptions.DefaultChallengeScheme = "smart";
            )
            .AddPolicyScheme("smart", "Authorization Bearer or OIDC", options =>
            
                options.ForwardDefaultSelector = context =>
                
                    var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();
                    if (authHeader?.StartsWith("Bearer ") == true)
                    
                        return JwtBearerDefaults.AuthenticationScheme;
                    
                    return OpenIdConnectDefaults.AuthenticationScheme;
                ;
            )
            .AddJwtBearer(o =>
            
                o.Authority = Configuration["JWT:Authentication:Authority"];
                o.Audience = Configuration["JWT:Authentication:ClientId"];
                o.SaveToken = true;
            )
            .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
            .AddAzureAd(options => Configuration.Bind("AzureAd", options));

        services
            .AddMvc(config =>
            
                var policy = new AuthorizationPolicyBuilder()
                                 .RequireAuthenticatedUser()
                                 .Build();
                // Authentication is required by default
                config.Filters.Add(new AuthorizeFilter(policy));
                config.RespectBrowserAcceptHeader = true;
            );
            
            ...
            
            

Edición del 07/2019: debo agregar un enlace a la siguiente propuesta, porque también es muy útil: no puede usar parámetros en AddAuthentication() como lo hice yo, porque esto configuraría un esquema predeterminado. Todo está bien explicado aquí: use la autenticación de portador JWT múltiple. Me gusta mucho este otro enfoque!

Navegar por estos cambios ha sido difícil, pero supongo que estoy haciendo mal .AddScheme.

no use el AddScheme: es un método de bajo nivel diseñado para escritores de controladores.

¿Cómo configuro varios esquemas de autenticación en ASP.NET Core 2.0?

Para registrar el controlador de cookies, simplemente haga:

public class Startup

    public void ConfigureServices(IServiceCollection services)
    
        services.AddAuthentication(options =>
        
            options.DefaultScheme = "myauth1";
        )

       .AddCookie("myauth1");
       .AddCookie("myauth2");
    

    public void Configure(IApplicationBuilder app)
    
        app.UseAuthentication();

        // ...
    

Es importante tener en cuenta que no puede registrar varios esquemas predeterminados como podía hacerlo en 1.x (el objetivo de esta enorme refactorización es evitar tener varios middleware de autenticación automática al mismo tiempo).

Si es absolutamente necesario emular este comportamiento en 2.0, puede escribir un middleware personalizado que llama manualmente AuthenticateAsync() y crea un ClaimsPrincipal que contiene todas las identidades que necesita:

public class Startup

    public void ConfigureServices(IServiceCollection services)
    
        services.AddAuthentication(options =>
        
            options.DefaultScheme = "myauth1";
        )

       .AddCookie("myauth1");
       .AddCookie("myauth2");
    

    public void Configure(IApplicationBuilder app)
    
        app.UseAuthentication();

        app.Use(async (context, next) =>
        
            var principal = new ClaimsPrincipal();

            var result1 = await context.AuthenticateAsync("myauth1");
            if (result1?.Principal != null)
            
                principal.AddIdentities(result1.Principal.Identities);
            

            var result2 = await context.AuthenticateAsync("myauth2");
            if (result2?.Principal != null)
            
                principal.AddIdentities(result2.Principal.Identities);
            

            context.User = principal;

            await next();
        );

        // ...
    

La solución de https://stackoverflow.com/a/51897159/4425154 ayuda. Un par de elementos a considerar además de la solución mencionada,

  1. Asegúrese de estar utilizando .net core run-time 2.1 o superior
  2. Asegúrese de tener una política de autorización como se menciona a continuación si está utilizando middleware

       services.AddMvc(options =>
        
            var defaultPolicy = new AuthorizationPolicyBuilder(new[]  CookieAuthenticationDefaults.AuthenticationScheme, JwtBearerDefaults.AuthenticationScheme, OpenIdConnectDefaults.AuthenticationScheme )
                      .RequireAuthenticatedUser()
                      .Build();
            options.Filters.Add(new AuthorizeFilter(defaultPolicy));
        )
    

Si te animas, tienes la opción de dejar una división acerca de qué le añadirías a esta reseña.

¡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 *