Basic Authentication In .NET Core 5.0

In this, Article we are going to learn how to implement basic authentication in .Net Core 5.0

Prerequisites

We will apply Basic Authentication in our application to prevent our API from anonymous access, so only authorized users can access API.

Let us understand it by example.

First, open Visual Studio 2019 and create a .NET Core 5.0 application.

Following is the folder structure of my project.

Create UsersController in the controller folder and paste the below code.

[Authorize]
[Route("api/Users")]
[ApiController]
public class UsersController : Controller
{
  private IUserServices _userService;
  public UsersController(IUserServices userService)
  {
    _userService = userService;
  }

  [HttpGet]
  [Route("GetAllUsers")]
  public async Task<IActionResult> GetAllUsers()
  {
    var users = await _userService.GetAllUsers();
    return Ok(users);
  }
}

Create User class in a Model folder and paste the below code.

public int Id { get; set; }
public string Username { get; set; }
public string Password { get; set; }

Create IUserServices in the Service folder and paste the below code.

Task<User> Authenticate(string username, string password);
Task<IEnumerable<User>> GetAllUsers();

Create BasicAuthenticationHandler class in AuthHelper folder and paste the below code.

 public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
  {
    private readonly IUserServices _userService;

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

    protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
    {
      
      var endpoint = Context.GetEndpoint();
      if (endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null)
        return AuthenticateResult.NoResult();

      if (!Request.Headers.ContainsKey("Authorization"))
        return AuthenticateResult.Fail("Missing Authorization Header");

      User user = null;
      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("Invalid Authorization Header");
      }

      if (user == null)
        return AuthenticateResult.Fail("Invalid Username or Password");

      var claims = new[] {
                new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
                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);
    }
}

Create UserServices in the services folder and paste the below code.

public class UserServices : IUserServices
{
        private List<User> _users = new List<User>
        {
            new User { Id = 1, Username = "admin", Password = "admin" }
        };

    public async Task<User> Authenticate(string username, string password)
    {

      var user = await Task.Run(() => _users.SingleOrDefault(x => x.Username == username && x.Password == password));
      if (user == null)
        return null;
      return user;
    }

    public async Task<IEnumerable<User>> GetAllUsers()
    {
      return await Task.Run(() => _users);
    }
}

Add the following code in ConfigureServices in a startup.cs

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

Add the following code in Configure in a startup.cs

app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();

OutPut

Conclusion

In this article, you can see that we cannot directly access API, If we try to get access API directly or by using the wrong username and password then it will give unauthorized access issue, When you enter the correct password and username then you can use API and it will give correct output as you can see in the above video.

Also, Check Pivot Table In SQL

Submit a Comment

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

Subscribe

Select Categories