Home > Mobile >  Dynamically chose authentication scheme in ASP.net Core Wep Api
Dynamically chose authentication scheme in ASP.net Core Wep Api

Time:12-01

I am porting a self-hosted web API built using OWIN and the .NET Framework to a ASP.NET Core Web API (using .NET 6.0)

In the original API, I have a custom authentication mechanism that selects the authentication scheme for each call dynamically, based on a header in the request:

HttpListener listener = (HttpListener)appBuilder.Properties["System.Net.HttpListener"];
listener.AuthenticationSchemeSelectorDelegate = new AuthenticationSchemeSelector((httpRequest) =>
{
    if(httpRequest.Headers.AllKeys.Any(k => k == "MyCustomHeader"))
    {
        return AuthenticationSchemes.Ntlm;
    }
    else
    {
        return AuthenticationSchemes.Anonymous;
    }
});

Basically, for each request I check a specific header in the request and based on that I chose whether to force the request to use Windows Authentication or to allow the request to proceed anonymously.

How can I replicate this behavior in ASP.net Core web api? I found out how to use Windows Authentication by using the Microsoft.AspNetCore.Authentication.Negotiate NuGet package and configuring:

services.AddAuthentication(NegotiateDefaults.AuthenticationScheme)
                .AddNegotiate();

however, I don't know how to dynamically select whether to use that scheme or allow anonymous call based on the header like I did before.

Is this possible? How can I do it?

CodePudding user response:

Here is a kind of approach

services.AddAuthentication(opts =>
    {
        opts.DefaultScheme = "DynamicAuthenticationScheme";
    })
    .AddScheme<SystemSessionAuthenticationRelatedOptions, SystemAuthenticationRelatedHandler>(
        CommonConstants.SessionAuthentication, x => x.Test = "Ran in here")
    .AddCookie("CookieScheme")
    .AddJwtBearer(options =>
    {
        options.Authority = identityUrl;
        options.Audience = "shipping";
        options.RequireHttpsMetadata = false;
    })
    .AddPolicyScheme("DynamicAuthenticationScheme", "Default system policy",
        cfgOpts => cfgOpts.ForwardDefaultSelector = ctx =>
            ctx.Request.Headers.ContainsKey("IsTheSecretHeaderPresent?")
                ? "CookieScheme"
                : JwtBearerDefaults.AuthenticationScheme);

The idea was specify a default authentication scheme to DynamicAuthenticationScheme, and we add 2 more authentication scheme named CookieScheme and JwtBearerDefaults.AuthenticationScheme constant for Cookie and Jwt authentication correspondingly.

Then define our default authentication scheme as a routing for authentication mechanism based on the header info.

  • Related