Etchelon
Etchelon

Reputation: 912

Identity Server 4 - cancel redirect to login and return 401 instead

I had an ASP.NET Core 2 web app without Identity Server where I configured the automatic challange of unauthenticated HTTP requests to not redirect the user to the login page and just return 401 instead:

services.ConfigureApplicationCookie(config =>
        {
            config.Events.OnRedirectToLogin = ctx =>
            {
                ctx.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
                return Task.CompletedTask;
            };
        });

How can I achieve the same with Identity Server 4 integration? I tried to use the same code inside the AddOpenIdConnect configuration method:

.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.Events.OnRedirectToIdentityProvider = ctx =>
    {
        ctx.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
        return Task.CompletedTask;
    };
    [...]
})

It doesn't work though, the server returns a 302 anyway...

Upvotes: 5

Views: 1667

Answers (2)

Arad
Arad

Reputation: 12851

For anyone encountering this issue in the future, the reason changing the status code in OnRedirectToIdentityProvider doesn't seem to work (as was mentioned in the original question) is because you actually need to call context.HandleResponse() afterwards as well, which, according to its description "Skips any default logic for this redirect.".

Very obscure, I know, but that's how it's done. To use OP's example, this would work:

.AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme, options =>
{
    options.Events.OnRedirectToIdentityProvider = ctx =>
    {
        ctx.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
        ctx.HandleResponse(); // IMPORTANT
        return Task.CompletedTask;
    };
    [...]
})

Upvotes: 1

Anonymous Creator
Anonymous Creator

Reputation: 3819

It's too late I guess, but following worked for me. if someone has similar issue. (context.HandleResponse(); is important in OP case)

options.Events.OnRedirectToIdentityProvider = context =>
                 {
                     if (context.Request.Path.StartsWithSegments("/api"))
                     {
                         if (context.Response.StatusCode == (int)HttpStatusCode.OK)
                         {
                             context.ProtocolMessage.State = options.StateDataFormat.Protect(context.Properties);
                             context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                             context.Response.Headers["Location"] = context.ProtocolMessage.CreateAuthenticationRequestUrl();
                         }
                         context.HandleResponse();
                     }
                     return Task.CompletedTask;
                 };

Upvotes: 7

Related Questions