JavaFox
JavaFox

Reputation: 597

ASP.NET Core 2 Authorize attribute jwt

Please tell me why this code doesn't work.

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthentication(options =>
        {
            options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
            options.RequireHttpsMetadata = false;
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidIssuer = AuthOptions.ISSUER,
                ValidateAudience = true,
                ValidAudience = AuthOptions.AUDIENCE,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = AuthOptions.GetSymmetricSecurityKey()
            };
        });

        services.AddDbContext<ApplicationContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        services.AddIdentity<User, IdentityRole>().AddEntityFrameworkStores<ApplicationContext>();
        services.AddMvc();
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseAuthentication();

        app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller}/{action}/{id?}",
                defaults: new { controller = "Home", action = "Index" });
        });
    }
}

I tried delete options.Default* and replace it to only JwtBearerDefaults.AuthenticationScheme. Just only if I change [Authorize] to [Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)] it works. But I don't want use AuthenticationSchemes property for each attribute.

Upvotes: 1

Views: 1025

Answers (1)

poke
poke

Reputation: 387785

services.AddIdentity(…) sets up ASP.NET Core Identity which registers multiple Cookie authentication schemes using the Cookie authentication which are required for the form-based identity logins to work.

As part of that, it also sets up the default authentication and challenge schemes to IdentityConstants.ApplicationScheme.

Since you call AddIdentity after AddAuthentication, the default configuration you did for the latter will be overwritten by the identity configuration. So to fix your problem, you will have to make sure that you set the default schemes in the identity options after registering Identity.

services.AddIdentity<User, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationContext>();;

services.AddAuthentication(options =>
{
    options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultSignInScheme = JwtBearerDefaults.AuthenticationScheme;
})
    .AddJwtBearer(…);

Note that this will obviously stop the authentication cookie of ASP.NET Core Identity to be the default authentication and challenge scheme. So if your application also has areas where your are not using JWT Bearer, then those will stop working and will require explicit Authenticate attributes to switch back to the Identity cookie.

Upvotes: 7

Related Questions