Search code examples
c#asp.net-corejwtasp.net-core-identity

Why should I define JwtBearerDefaults.AuthenticationScheme for my Authorize attribute always?


I have a simple sample for JWT Authentication which you can find it here

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>

As you can see I have added JwtBearerDefaults.AuthenticationScheme to the Authentication inside Startup/ConfigureServices method so I should be able to use the [Authorize] standalone as following

[Authorize]
public sealed class WeatherForecastController : BaseController
{
    private static readonly string[] Summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

but I dont know why it does not work! (I have tested with Postman). I must define it via AuthenticationSchemes.

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public sealed class WeatherForecastController : BaseController
{
    private static readonly string[] Summaries = new[]
    {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
    };

Can any one guide me how can I use Authorize attribute standalone without AuthenticationSchemes especially when I have defined it inside ConfigureServices? What did I set wrong?


Solution

  • Your code does not have app.UseAuthentication() included. So that means there is no authentication middleware.

    The default authentication scheme is used only by the authentication middleware to auto-authenticate the request and build-up the current principal. When you use [Authorize] alone, the authentication schemes are not set and the authorization filters will not work. The filter built from that IAuthorizeData (AuthorizeAttribute is an IAuthorizeData) is an AuthorizeFilter and this requires the schemes to be set explicitly.

    That's why the other [Authorize(...)] with some scheme set works but not the [Authorize].

    So you should use the authentication middleware to use [Authorize] conveniently without having to specify the schemes.

    The AuthorizeFilter will use IPolicyEvaluator internally to authenticate the request, here's the default implementation of PolicyEvaluator.AuthenticateAsync - you can see it checks for the availability of AuthenticationSchemes.