简体   繁体   中英

.net core 3.0 authorize attribute with Policy, AuthenticationSchemes

I am trying to implement two authentication schemes in my app. In controller with authorize attribute, I set scheme that the controller has to use to authenticate. register auth:

Startup:

 public class Startup
    {

        public void ConfigureServices(IServiceCollection services)
        {
            services.ConfigureAuthentication();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseAuthentication();
            app.UseAuthorization();
        }
    }

AuthenticationExtensions.cs:

public static class AuthenticationExtensions
{

public static IServiceCollection ConfigureAuthentication(this IServiceCollection services)
{
    services.AddAuthentication(AuthConstants.DefaultScheme)
        .AddScheme<AuthenticationSchemeOptions, DefaultSchemeHandler>(AuthConstants.DefaultScheme, AuthConstants.DefaultScheme, null)
        .AddScheme<AuthenticationSchemeOptions, IdentityAuthenticationHandler>(AuthConstants.IdentityScheme, AuthConstants.IdentityScheme, null);

    services.AddAuthorization(options =>
    {
        options.AddPolicy("IdentityAuthPolicy", policy =>
        {
            policy.AuthenticationSchemes.Add(AuthConstants.IdentityScheme);
            policy.RequireAuthenticatedUser();
        });
    });

    return services;
}

}

In the controller, I define which authentication schemes to use:

[Authorize(AuthenticationSchemes = AuthConstants.IdentityScheme)]
[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{}

Problem: app tries to authenticate with default scheme after failing, tries the one that is specified in authorize attribute. I want the app to use the only authentication scheme that I've defined in authorize attribute. Also, I've tried to use Policy, but the outcome was the same.

You should:

  1. Add the Controllers Service

  2. Set up routing by adding the routing-related middlewares

  3. Register the Authorization middleware first by calling app.UseAuthorization() before app.UseAuthentication()

Here is how your Startup class code should like:

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication(AuthConstants.DefaultScheme)
        .AddScheme<AuthenticationSchemeOptions, DefaultSchemeHandler>(AuthConstants.DefaultScheme, AuthConstants.DefaultScheme, null)
        .AddScheme<AuthenticationSchemeOptions, IdentityAuthenticationHandler>(AuthConstants.IdentityScheme, AuthConstants.IdentityScheme, null);

    services.AddAuthorization(options =>
    {
        options.AddPolicy("IdentityAuthPolicy", policy =>
        {
            policy.AuthenticationSchemes.Add(AuthConstants.IdentityScheme);
            policy.RequireAuthenticatedUser();
        });
    });

    services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseRouting();

    app.UseAuthorization();
    app.UseAuthentication();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Afterwards, either use the AuthenticationSchemes property of the [Authorize] attribute or its Policy property:

[Authorize(AuthenticationSchemes = AuthConstants.IdentityScheme)]
//[Authorize(Policy = "IdentityAuthPolicy")]
[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM