Search code examples
c#asp.net-coreasp.net-core-mvcasp.net-core-2.0ws-federation

How do I return a 401 status instead of a 302 redirect after cookie has expired?


I'm using cookie authentication without Identity and the following Nuget packages:

<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.5" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.WsFederation" Version="2.0.3" />

I'm setting a short timeout on my cookie and wanting my API calls to return a 401 status instead of a 302 redirect when the cookie has expired. My ConfigureServices looks like the following:

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IRestService, RestService>();

    services.AddDataProtection()
        .SetApplicationName("AspNetCookieShare")
        .PersistKeysToFileSystem(new DirectoryInfo(Configuration["DataProtectionKeyDirectory"]));

    services.AddAuthentication(sharedOptions =>
        {
            sharedOptions.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
            sharedOptions.DefaultChallengeScheme = WsFederationDefaults.AuthenticationScheme;
        })
        .AddWsFederation(options =>
        {
            options.Wtrealm = Configuration["Wtrealm"];
            options.MetadataAddress = "http://example.com/metadata.xml";
            options.SkipUnrecognizedRequests = true;
            options.RequireHttpsMetadata = false;
            options.UseTokenLifetime = false;
        })
        .AddCookie(options =>
        {
            options.ExpireTimeSpan = TimeSpan.FromSeconds(10);
            options.Cookie.Expiration = TimeSpan.FromSeconds(10);
            options.Cookie.Name = "AspNetShared";
            options.Cookie.Path = "/";

            options.Events.OnRedirectToLogin = context =>
            {
                context.Response.StatusCode = 401;
                return Task.CompletedTask;
            };
        });

    services.AddMvc();
}

I'm using OnRedirectToLogin, however, I'm still getting 302 response and not a 401 after the cookie has expired:

image

What am I doing wrong?


Solution

  • I changed my services.AddWsFederation() to the following and it appears to be working:

    .AddWsFederation(options =>
    {
        options.Wtrealm = Configuration["Wtrealm"];
        options.MetadataAddress = "http://example.com/metadata.xml";
        options.SkipUnrecognizedRequests = true;
        options.RequireHttpsMetadata = false;
        options.UseTokenLifetime = false;
        options.Events.OnRedirectToIdentityProvider = context =>
        {
            context.Response.StatusCode = 401;
            context.HandleResponse();
            return Task.CompletedTask;
        };
    })