I'm quite frustrated about the fact that an authentication scheme appears to be mandatory in Asp.Net Core. My objective is to build an API and I don't want to know anything about the client. I've built custom authentication and authorization, which works fine. I'm not using identity or cookies. However, I can't return a 403 Forbid result without a valid authentication scheme, otherwise I get the following exception...
System.InvalidOperationException: No authentication handler is configured to handle the scheme: Automatic
My question is, can I configure MVC to not use an authentication scheme or create an authentication scheme without the reliance on a login path or any path for that matter?
After poring over the Asp.net Core security source code, I've managed to create a custom authentication handler. To do this you need to implement 3 classes.
The first class implements an abstract AuthenticationOptions.
public class AwesomeAuthenticationOptions : AuthenticationOptions {
    public AwesomeAuthenticationOptions() {
        AuthenticationScheme = "AwesomeAuthentication";
        AutomaticAuthenticate = false;
    }
}
The second class implements an abstract AuthenticationHandler.
public class AwesomeAuthentication : AuthenticationHandler<AwesomeAuthenticationOptions>
{
    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var prop = new AuthenticationProperties();
        var ticket = new AuthenticationTicket(Context.User, prop, "AwesomeAuthentication");
        //this is where you setup the ClaimsPrincipal
        //if auth fails, return AuthenticateResult.Fail("reason for failure");
        return await Task.Run(() => AuthenticateResult.Success(ticket));
    }
}
The third class implements an abstract AuthenticationMiddleware.
public class AwesomeAuthenticationMiddleware : AuthenticationMiddleware<AwesomeAuthenticationOptions>
{
    public AwesomeAuthenticationMiddleware(RequestDelegate next, 
        IOptions<AwesomeAuthenticationOptions> options,
        ILoggerFactory loggerFactory,
        UrlEncoder urlEncoder) : base(next, options, loggerFactory, urlEncoder) {
    }
    protected override AuthenticationHandler<AwesomeAuthenticationOptions> CreateHandler()
    {
        return new AwesomeAuthentication();
    }
}
Finally, you use the middleware component in the Startup.cs Configure method.
app.UseMiddleware<AwesomeAuthenticationMiddleware>();
Now you can build your own Authentication Schemes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With