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.