In this tutorial, you will learn how to implement basic authentication in asp.net core web API.
We create a class called “BasicAuthentication.cs” and write the following code.
In this class, we have to override the task called HandleAuthenticateAsync
Basically we have to look for Authorization key in http header Request.Headers.ContainsKey("Authorization")
, if no key found we simply fail the authentication.
If Authorization key found, then we have to retrieve the key value from the string, Key value are stored in {userKey}:{userPassword}
format.
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 DTO.Authenticate(username, password);
using Microsoft.AspNetCore.Authentication; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using System; using System.Net.Http.Headers; using System.Security.Claims; using System.Text; using System.Text.Encodings.Web; using System.Threading.Tasks; public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions> { 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("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 DTO.Authenticate(username, password); } catch { return AuthenticateResult.Fail("Invalid Authorization Header"); } if (user == null) return AuthenticateResult.Fail("Invalid Username or Password"); var claims = new Claim[] { new Claim(ClaimTypes.NameIdentifier, user.UserId.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); } }
Now to apply basic authentication class attribute on any action method you just need to add [Authorize]
on top as attribute.
[Authorize] [Route("GetOrders")] [HttpGet] [ProducesResponseType(typeof(IEnumerable<Order>), (int)HttpStatusCode.OK)] public async Task<IActionResult> GetOrders() { //var userid = _userService.GetUserIdentity(); var orders = await _queryService.GetNewOrdersAsync(); return Ok(orders); }
In "ConfigureServices" method configure Basic Authentication with AddAuthentication
public void ConfigureServices(IServiceCollection services) { services.AddControllers(); services.Configure<DbConnection>(Configuration.GetSection("DbConnectionConfig")); services.AddAuthentication("BasicAuthentication") .AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>("BasicAuthentication", null); services.AddScoped<IQueryService, QueryService>(); }
In "Configure" method register the app.UseAuthentication();
method.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseAuthentication(); app.UseAuthorization(); }
At the end, you need to make sure, if basic authentication is working properly, so either of following method will help you.