Basic Authentication in REST API Dot Net Core

Basic Authentication in REST API Dot Net Core (authenticate user from DB)
In this tip you will learn how to authenticate user to request. you must add authentication header to request from api.
1. Create your authentication class and inherit it from AuthenticationHandler<AuthenticationSchemeOptions> 
2. Create table in database and store user name and password. 
3. Create Store Procedure to select user 4. Create business logic/database logic in your project.
Step by step implementation
Step 1. Create table
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
CREATE TABLE [dbo].[tblAdminApiAuth](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[UserName] [nvarchar](50) NULL,
	[Password] [nvarchar](50) NULL,
 CONSTRAINT [PK_tblAdminApiAuth] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

INSERT INTO [tblAdminApiAuth]([UserName],[Password])
		   VALUES ('Admin' ,'pass67678hasdfsdfyrwq$#')

GO
Stored Procedure
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
create PROCEDURE [dbo].[sp_Admin_ApiAuthenticate]
	@username			nvarchar(500),
	@password			nvarchar(500)
	
AS
BEGIN
declare @flag as bit=0
	if exists(
	select id from tblAdminApiAuth with(nolock) where UserName=@username and Password=@password)
	begin
	set @flag=1
	end
	select @flag as isAuthenticate
END
interface.
1
2
3
4
public interface IAPIAuthenticationService
    {
        bool IsAuthorizedUser(string username,string password);
    }
Create class and implement the interface
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
 
public class APIAuthenticationService : IAPIAuthenticationService
    {
     private DataContext db=new DataContext();
        public bool IsAuthorizedUser(string username, string password)
        {
            try
            {
                var cmd = db.LoadStoredProc("sp_Admin_ApiAuthenticate").WithSqlParam("@username", username).WithSqlParam("@password", password);
                var _isAuthenticate = cmd.ExecuteStoredProc<APIAuthenticationModel>();
// Please read the following articles for executing stored procedure.
//http://asptipsandtricks.blogspot.com/2021/02/enabling-code-first-in-aspnet-core-mvc.html
//http://asptipsandtricks.blogspot.com/2021/02/Stored-Procedure-in-Entity-Framework-Core.html
                return _isAuthenticate[0].isAuthenticate;
            }
            catch (Exception ae)
            {
                throw new Exception(ae.Message);
            }
        }
    }
Create Basic Authentication Handler
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
using System.Text.Encodings.Web;
using System.Threading.Tasks;

namespace MyApi.Helper
{
    public class BasicAuthenticationHandler:AuthenticationHandler<AuthenticationSchemeOptions>
    {
        private static readonly IAPIAuthenticationService _apiAuthentcationService=new APIAuthenticationService();
        public BasicAuthenticationHandler(
            IOptionsMonitor<AuthenticationSchemeOptions> options,
            ILoggerFactory logger,
            UrlEncoder encoder,
            ISystemClock clock)
           
            : base(options, logger, encoder, clock)
        {
            
        }

        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
        {
            // skip authentication if endpoint has [AllowAnonymous] attribute
            var endpoint = Context.GetEndpoint();
            if (endpoint?.Metadata?.GetMetadata<IAllowAnonymous>() != null)
                return AuthenticateResult.NoResult();

            if (!Request.Headers.ContainsKey("Authorization"))
                return AuthenticateResult.Fail("Missing Authorization Header");
           var user = false;
           string username ="";
           string password ="";
            try
            {
                var authHeader = AuthenticationHeaderValue.Parse(Request.Headers["Authorization"]);
                var credentialBytes = Convert.FromBase64String(authHeader.Parameter);
                var credentials = Encoding.UTF8.GetString(credentialBytes).Split(new[] { ':' }, 2);
                username = credentials[0];
                password = credentials[1];
                user = _apiAuthentcationService.IsAuthorizedUser(username, password);
            }
            catch
            {
                return AuthenticateResult.Fail("Invalid Authorization Header");
            }

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

            var claims = new[] {
                new Claim(ClaimTypes.NameIdentifier, password),
                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);
        }
    }
}
Place Authorize attribute on your controller "[Authorize]"
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;

namespace MyApi.Controllers
{
    [Authorize]
    [ApiController]
    [Route("[controller]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        private readonly ILogger<WeatherForecastController> _logger;

        public WeatherForecastController(ILogger<WeatherForecastController> logger)
        {
            _logger = logger;
        }

        [HttpGet]
        public IEnumerable<WeatherForecast> Get()
        {
            var rng = new Random();
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateTime.Now.AddDays(index),
                TemperatureC = rng.Next(-20, 55),
                Summary = Summaries[rng.Next(Summaries.Length)]
            })
            .ToArray();
        }
    }
}

Usage in Request (Screen Shot)




Usage in Request (Sample get request)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;

namespace MyCoreProject
{
    public class RequestResponseHelper<T> where T : class
    {
       public static async Task<T> Get(string url)
        {
            string userName ="Admin";
            string password ="pass67678hasdfsdfyrwq$#"
            HttpClient client = new HttpClient();

            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
        AuthenticationSchemes.Basic.ToString(),
        Convert.ToBase64String(Encoding.ASCII.GetBytes($"{userName}:{password}"))
        );

            client.BaseAddress = new Uri(url);

            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            using (HttpResponseMessage response = await client.GetAsync(url))
            {
                if (response.IsSuccessStatusCode)
                {

                    var returnResult = response.Content.ReadAsAsync<T>().Result;
                    return returnResult;
                }
            }

            return null;
        }
    }
}




Post a Comment