Basic Authentication in ASP.NET Core with example

Today in this article we will learn how to secure ASP.NET Core API using Basic Authentication in .NET Core with simple easy to understand examples.

We shall cover below aspects of enabling Basic Authentication in ASP.NET Core API,

ASP.NET Core 3.1 or 5.0 support

Please refer to below article,

What is Basic Authentication

HTTP Basic authentication is one of the simplest techniques for enforcing restricted access to web resources.

This technique is often used by the organization internally within their LAN infrastructure or secured gateway for accessing internal resources effectively.

Basic authentication is an Authentication Scheme built into the HTTP protocol which uses a simple UserName and Passwords to access a restricted resource.

These UserName and Passwords are translated to standard “Authorization” headers using Bas64 encoding.

Command

Authorization: Basic <credentials(base64)>

If you have UserName and Password is as “Test“, “Password” then Base64 string should be as below,

Authorization: Basic VGVzdDpQYXNzd29yZA===

Note: 

Because base64 can easily be decoded, It’s recommended using Basic authentication using HTTPS/SSL only.

Getting started

Create ASP.NET Core 2.2 project

Enable Basic Authentication scheme

We shall be using an Authentication handler for implementing Basic Authentication. An authentication handler will Construct AuthenticationTicket objects representing the user’s identity if authentication is successful. This handler will be responsible for authenticating users.

In Startup.cs please update ConfigServices() method to register Basic Authentication scheme.

Please use AddAuthentication() extension methods for setting up authentication services in a ServiceCollection as below.

services.AddAuthentication("BasicAuthentication").
            AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>
            ("BasicAuthentication", null);


Create Authentication handler – BasicAuthenticationHandler

An authentication handler will enable the scheme and authenticate the users. We shall be leveraging on the use of AuthenticationHandler<TOptions> to challenge the credentials passed.

You may want to set up the configuration accordingly if supporting multiple authentication scheme in the same API.

Please derive your BasicAuthenticationHandler from Abstract class AuthenticationHandler<TOptions> as shown below.

 
public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
    {
..
     }

Please override the methods exposed by the class AuthenticationHandler,

Below is the empty template of the method,

 
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            throw new NotImplementedException();
        }


Performing Authentication

Please update the method for the below logic to verify header credentials for their validity ,

          User user;

             try
            {
                var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
                var credentialBytes = Convert.FromBase64String(authHeader.Parameter);
                var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] { ':' }, 2);
                var username = credentials[0];
                var password = credentials[1];
                user = await _userService.Authenticate(username, password);
            }
            catch
            {
                return AuthenticateResult.Fail("Error Occured.Authorization failed.");
            }

            if (user == null)
                return AuthenticateResult.Fail("Invalid Credentials");


Construct AuthenticationTicket objects

Create AuthenticationTicket objects for the user’s identity as below.

        var claims = new[]
            {
                new Claim(ClaimTypes.NameIdentifier, user.Id),
                new Claim(ClaimTypes.Name, user.Username),
            };

            var identity = new ClaimsIdentity(claims, Scheme.Name);
            var principal = new ClaimsPrincipal(identity);

            var ticket = new AuthenticationTicket(principal, Scheme.Name);

            return AuthenticateResult.Success(ticket);


Based on Users’ identity success or failure authorization can be allowed or forbidden the access the resources.

Below is the UserService implementation. You can add your custom validation to this method as per your requirements.

public interface IUserService
    {
        Task<User> Authenticate(string username, string password);
    }

User class is defined as below,

public class User
    {
        public string Id { get; internal set; }
        public string Username { get; internal set; }
    }

API pipeline needs to be updated as below,

 

public void ConfigureServices(IServiceCollection services)
        {
            
 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
            services.AddTransient<IUserService, UserService>();
            services.AddAuthentication("BasicAuthentication").
            AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null);

        }

Update Configure method as below,

 
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseAuthentication();
            app.UseHttpsRedirection();
            app.UseMvc();
        }

Invoking Secured method

Here I am using POSTMAN as a client to verify the token and invoke a secured GET method.

As shown below API response is 200 OK (successful).

200 OK (successful)

Let’s validate the GET method which is secured using [Authorize] attribute,

Or Using PostMan,

blank

Let’s execute the API with Invalid Header. You will start noticing Error 401: Unauthorized

 Error 401: Unauthorized

blank

That’s All, Happy Coding !!

Do you have any comments or ideas or any better suggestions to share?

Please sound off your comments below.

Happy Coding !!

References:

Summary

Secured programming is not an afterthought process. It needs to be considered on day first. Today in this article we learned how to secure ASP.NET Core 2.2 API using Basic Authentication with simple easy to understand examples.



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.



Leave a Reply

Your email address will not be published. Required fields are marked *