CoffeeRoll
CoffeeRoll

Reputation: 5

ASP.NET Core API Authentication with JWT breaks built-in authentication for website

I'm working on an ASP.NET Core project that has a website as well as an API. I need the API to be secured by some means, so I implemented JWT authentication. This worked as expected, and the API is only accessible by calls made with a valid token.

The problem is, the built-in login functionality on the website no longer works. This is the code I added to Startup.cs:

services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(o =>
    {
        o.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ValidIssuer = Configuration["Jwt:Issuer"],
            ValidAudience = Configuration["Jwt:Issuer"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
        };
    });

If I remove this code, the built-in login feature works as usual, but the API no longer works.

Is there a way I can make the JWT authentication only apply to the API controllers? Or is there a way I can make the built-in authentication use JWT?

Upvotes: 0

Views: 359

Answers (1)

Steve
Steve

Reputation: 216293

I had the same problem and resolved it (using Asp.Net Core 3.0).
You can add more than one Authentication schema to your project with code like this.

// Read the token generation data...
var token = Configuration.GetSection("JwtTokenData").Get<JwtTokenData>();

services.AddAuthentication()
        .AddCookie(options =>
        {
            options.LoginPath = $"/Identity/Account/Login";
            options.AccessDeniedPath = $"/Identity/Account/AccessDenied";
        })
        .AddJwtBearer(options => {
            options.SaveToken = true;
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes(token.Secret)),
                ValidIssuer = token.Issuer,
                ValidAudience = token.Audience,
                ValidateIssuer = false,
                ValidateAudience = false
            };
        });

Notice how I haven't specified the default authentication schema when I call AddAuthentication. This allows the built-in Authentication to be the default for your pages or controller where you use the [Authorize] attribute.

But when you need to use JWT Authentication then you use this option on the Authorize attribute for your Web API controller or methods

[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]

Upvotes: 2

Related Questions