15

I want to use a secret key (api key) authorization asp.net core web api. The key will be passed in Authorization header like given below,

ex. Authorization keytype;h43484344343bbhfdjfdfhj34343

I want to write a middleware to read this key from request headers and call an internal api to validate the key.

In web api we can write a message handler to do this, but I am new to asp.net core. I'm seeing a lot of samples but they are using inbuilt JWT token authentication. But I wanted to use my own key and I decrypt this key and validate against a database entry.

Can anyone suggest some code samples on how to do this?

2
  • What version of asp core are you using? Commented Oct 4, 2017 at 7:45
  • .net core 1.1 is my target framework Commented Oct 4, 2017 at 13:58

1 Answer 1

26

I have used this approach in a solution using asp core 1.1. First define a custom scheme:

public static class Authentication
{
    public const string Scheme = "Custom";
}

You then have to inherit AuthenticationHandler<TOptions>. Here is where the logic for validating the header value will go:

public class MyAuthenticationHandler : AuthenticationHandler<MyOptions>
{
    protected override Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        var authorizationHeader = Context.Request.Headers["Authorization"];
        if (!authorizationHeader.Any())
            return Task.FromResult(AuthenticateResult.Skip());

        var value = authorizationHeader.ToString();
        if (string.IsNullOrWhiteSpace(value))
            return Task.FromResult(AuthenticateResult.Skip());

        // place logic here to validate the header value (decrypt, call db etc)

        var claims = new[]
        {
            new Claim(System.Security.Claims.ClaimTypes.Name, "Bob")
        };

        // create a new claims identity and return an AuthenticationTicket 
        // with the correct scheme
        var claimsIdentity = new ClaimsIdentity(claims, Authentication.Scheme);

        var ticket = new AuthenticationTicket(new ClaimsPrincipal(claimsIdentity), new AuthenticationProperties(), Authentication.Scheme);

        return Task.FromResult(AuthenticateResult.Success(ticket));
    }
}

In order to inherit AuthenticationHandler you must create an options class where you set the AuthenticationScheme-property to the scheme you are using:

public class MyOptions : AuthenticationOptions
{
    AuthenticationScheme = Authentication.Scheme;
}

After this you have to inherit AuthenticationMiddleware<TOptions>. This will create the handler you implemented in the previous step:

public class MyAuthenticationMiddleware : AuthenticationMiddleware<MyOptions>
{
    public MyAuthenticationMiddleware(RequestDelegate next, IOptions<MyOptions> options, ILoggerFactory loggerFactory, UrlEncoder encoder) : base(next, options, loggerFactory, encoder)
    {
    }

    protected override AuthenticationHandler<MyOptions> CreateHandler()
    {
        return new MyAuthenticationHandler();
    }
}

In order to easily plug in your middleware you can define these extension methods:

public static IApplicationBuilder UseMyAuthentication(this IApplicationBuilder app, IConfigurationSection config)
{
    return app.UseMyAuthentication(options => {});
}

private static IApplicationBuilder UseMyAuthentication(this IApplicationBuilder app, Action<MyOptions> configure)
{
    var options = new MyOptions();
    configure?.Invoke(options);

    return app.UseMiddleware<MyAuthenticationMiddleware>(new OptionsWrapper<MyOptions>(options));
}

Then in your Startup class you can finally add your middleware:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseMyAuthentication(Configuration.GetSection("MyAuthenticationOptions"));

    // other stuff

    app.UseMvc();
}

Then add the AuthorizeAttribute on your actions specifying the scheme you just created:

[Authorize(ActiveAuthenticationSchemes = Authentication.Scheme)]
public IActionResult Get()
{
    // stuff ...
}

There are a lot of steps but hopefully this will get you going!

Sign up to request clarification or add additional context in comments.

6 Comments

Do you have the whole code in somewhere like GitHub etc?
Hold on, I´ll put up a sample
4+years later... or no sample
Weups my bad, here is a sample (old)
Check out this blog post on how to implement a custom authentication scheme in asp core 3.x: referbruv.com/blog/posts/…
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.