Tophat Gordon
Tophat Gordon

Reputation: 739

Overriden HandleUnauthorizedAsync not being called .NET Core

I have implemented my own custom authentication middleware and handler, and configured them in the app startup. This is all working fine.

In my custom auth handler where I have overriden HandleAuthenticateAsync() to do my own custom auth, I have also overriden HandleUnauthorizedAsync() in order to redirect the user to the login page, but this isn't getting called.

The browser is receiving a 401 (Unauthorized) in the response. I was expecting my HandleUnauthorizedAsync() to be called.

Am I not understanding the pipeline correctly here?

Thanks

Upvotes: 13

Views: 7619

Answers (5)

daveD
daveD

Reputation: 976

I know this is an old question, I hope this answer solves someones issues later. I had exactly the same issue, I implemented a AuthenticationHandler but the HandleAuthenticateAsync() method wasnt called, I just got a 401.

To solve it I changed this

builder.Services.AddAuthentication("BasicAuthentication")
            .AddScheme<AuthenticationSchemeOptions, MyBasicAuthenticationHandler>("BasicAuthentication", null);

To this

builder.Services.AddAuthentication("BasicAuthentication")
            .AddScheme<AuthenticationSchemeOptions, MyBasicAuthenticationHandler>("MyApiBasicAuthentication", null);

and decorated the controller with

[Microsoft.AspNetCore.Authorization.Authorize(AuthenticationSchemes = "MyApiBasicAuthentication")]

Using "BasicAuthentication" for the scheme name was the problem, I had copied the code directly from another source.

Upvotes: 1

mihails.kuzmins
mihails.kuzmins

Reputation: 1440

user1859022's helped in my case, but I didn't want to type a name of my scheme for every [Authorize]. And specifying DefaultAuthenticateScheme didn't work at first as well.

My mistake was kinda stupid. I had both app.UseAuthorization() and app.UseAuthentication() and of course the order was wrong. The correct version is

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
        app.UseDeveloperExceptionPage();

        app.UseHttpsRedirection();

        app.UseRouting();

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

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

So make sure that UseAuthentication is called before UseAuthorization.

In .NET7 they have simplified it so there lines of code can be used:

builder.Services.AddAuthentication().AddJwtBearer();
builder.Services.AddAuthorization();

Upvotes: 17

Dan
Dan

Reputation: 13343

Mihail's answer solved it for me, but just so that it's clear:

If your request is hitting ChallengeAsync but not HandleAuthenticateAsync or AuthenticateAsync

Then check your ordering:

  1. app.UseAuthentication();
  2. app.UseAuthorization();

Upvotes: 3

Kobus Pelser
Kobus Pelser

Reputation: 361

The above solution did work for me as well I was able to improve on it with following code segment, then there is no need to specify the authentication scheme name in the [Authorize] attribute. It is important to call the AddAuthentication method before AddMvc.

public void ConfigureServices(IServiceCollection services)
{
    //must be placed before the AddMvc call
    services.AddAuthentication(options => 
                {                    
                    options.DefaultAuthenticateScheme = "MyAuth";
                    options.DefaultChallengeScheme = "MyAuth";
                })
                .AddCustomAuth(o => { });
    
    services.AddMvc();
}

Upvotes: 4

user1859022
user1859022

Reputation: 2695

in my case the reason for my handler not being called was that my AuthenticationScheme wasn't selected as default. I had to include it in my Authorize attribute like this:

[HttpGet]
[Authorize(AuthenticationSchemes= "MyAuth")]
public IEnumerable<string> Get()
{
    ...
}

btw: the AutomaticChallenge option seems to have been removed in .net core 2.0

Upvotes: 12

Related Questions