12

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

Tratcher
  • 5,929
  • 34
  • 44
Tophat Gordon
  • 699
  • 2
  • 9
  • 22
  • I managed to get it to fire HandleUnauthorizedAsync() by setting AutomaticChallenge = true in my auth options. – Tophat Gordon May 16 '17 at 21:09
  • 1
    Any chance you can elaborate on this? By default custom auth middleware doesn't have AutomaticChallenge. How did you incorporate that? Am I missing an interface inheritance other than AuthenticationSchemeOptions? – BinaryPatrick Jan 16 '18 at 18:54

4 Answers4

16

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();
mihails.kuzmins
  • 1,140
  • 1
  • 11
  • 19
  • I know it's been a while, but I just needed to stop in here and say "bless you". I have been beating my head against ILSpy for the past day trying to understand the AuthorizationMiddleware. My custom token validator would go off, successfully validate the token, but then I would always dump into the Challenge event and the api call would come back with 401. I now know, that will be the behavior if you went with the project template defaults without thinking to go in and add app.UseAuthentication(); in the proper place. :) – Frog Pr1nce Jun 16 '20 at 20:24
  • ORDERING IS IMPORTANT So make sure that UseAuthentication is called before UseAuthorization. – Carlo V. Dango Jul 07 '20 at 11:42
  • I feel like an idiot, but this also solved my problem :D – Corey Jul 22 '20 at 15:28
12

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

user1859022
  • 2,585
  • 1
  • 21
  • 33
4

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();
}
Ramon Dias
  • 835
  • 2
  • 12
  • 23
Kobus Pelser
  • 231
  • 2
  • 6
2

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();
Dan
  • 12,808
  • 7
  • 45
  • 54