ASP.NET Core WebApi - Basic Authentication

6/25/2021

Working further on my new Quid WebApi, then next step is to add Authentication. I'm going to use basic authentication for this. Here is an overview of the steps I followed:

  • Custom AuthenticationHandler
  • Startup code
  • [Authorize] attribute
  • Get current user

Custom AuthenticationHandler

The bulk of the implementation is found in a custom object inheriting from AuthenticationHandler. For this I created a class called BasicAuthenticationHandler. Here is that class in its entirety:

public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
{
    public const string AuthHeaderName = "Authorization";

    public BasicAuthenticationHandler(
        IOptionsMonitor<AuthenticationSchemeOptions> options,
        ILoggerFactory logger,
        UrlEncoder encoder,
        ISystemClock clock) : base(options, logger, encoder, clock)
    {
    }

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
        if (!Request.Headers.ContainsKey(AuthHeaderName))
        {
            return AuthenticateResult.Fail("Authorization header was not found.");
        }

        // Grab the params and decrypt
        var authHeaderValue = AuthenticationHeaderValue.Parse(Request.Headers[AuthHeaderName]);
        var bytes = Convert.FromBase64String(authHeaderValue.Parameter);
        string[] credentials = Encoding.UTF8.GetString(bytes).Split(":");
        string username = null;

        // TODO: Add some custom validation code here:
        username = credentials[0]; // Just set it to the first string

        if (!string.IsNullOrEmpty(username)) 
        {
            var claims = new[] { new Claim(ClaimTypes.Name, username) };
            var identity = new ClaimsIdentity(claims, Scheme.Name);
            var principal = new ClaimsPrincipal(identity);
            var ticket = new AuthenticationTicket(principal, Scheme.Name);

            return AuthenticateResult.Success(ticket);
        }

        return AuthenticateResult.Fail("Unauthorized");
    }
}

The parameters coming in need to be UTF8 decrypted, which is done on lines 21-22. The credentials variables on line 23 looks like "username:password". Line 27 is where you would put some form of custom authentication. The rest of this class should be either self-explanatory, or "just works". The primary change you would need is line 27.

Startup code

The next set of code all appears in Startup.cs. The first is a one-liner in Create:

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...
        app.UseAuthentication();
        ...
    }

The next set of code is added to ConfigureServices:

    public void ConfigureServices(IServiceCollection services)
    {
        ...
        // Specify the Authentication for this app to use:
        services.AddAuthentication("BasicAuthentication") 
            .AddScheme<AuthenticationSchemeOptions, 
            BasicAuthenticationHandler>("BasicAuthentication", null);
        ...
    }

The "BasicAuthentication" pass to the constructor (line 5) is simply the custom class created above minus "Handle" on the end. Note this is also passed to AddScheme.

[Authorize] attribute

The last required step is to simply add the [Authorize] attribute to any Controller or Method that requires it. Here I place it on my QuidController:

    [Authorize]
    [ApiController]
    [Route("[controller]")]
    public class QuidController : ControllerBase
    {
        ...
    }

Get current user

If you have need of the current user, this can be obtained via the HttpContext:

    [HttpGet]
    [Route("AuthTest")]
    public string AuthTest()
    {
        string username = HttpContext.User.Identity.Name;
        return $"Welcome {username}";
    }

Wrapping up...

That's all that's needed for basic authentication on the service side. At this point, ensure all calls include basic authentication and include username & pwd. This can be tested easily from PostMan.

In Part II, I show how to make this call from an Android app.


Please register or login to add a comment.

Comments (displaying 1 - 1):
No comments yet! Be the first...


  • C#/.NET
  • T-SQL
  • HTML/CSS
  • JavaScript/jQuery
  • .NET 8
  • ASP.NET/MVC
  • Xamarin/MAUI
  • WPF
  • Windows 11
  • SQL Server 20xx
  • Android
  • XBox
  • Arduino
  • Skiing
  • Rock Climbing
  • White water kayaking
  • Road Biking