Asp.Net Core Web Api - BASIC Authentication Not working?

Cenk 1,036 Reputation points
2022-12-22T06:00:04.477+00:00

Hi,

I implemented a basic authentication handler. I debugged it, and even though it enters AuthenticateResult.Fail, I get a response OK from the service. Where is the problem?

Handler:

public class BasicAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>  
    {  
        private readonly IUserValidate _userValidate;  
        public BasicAuthenticationHandler(  
            IOptionsMonitor<AuthenticationSchemeOptions> options,  
            ILoggerFactory logger,  
            UrlEncoder encoder,  
            ISystemClock clock, IUserValidate userValidate) :  
            base(options, logger, encoder, clock)  
        {  
            _userValidate = userValidate;  
        }  
  
        protected override async Task<AuthenticateResult> HandleAuthenticateAsync()  
        {  
            Response.Headers.Add("WWW-Authenticate", "BASIC");  
  
            if (!Request.Headers.ContainsKey("Authorization"))  
            {  
                return await Task.FromResult(AuthenticateResult.Fail("Authorization header missing."));  
            }  
  
            // Get authorization key  
            var authorizationHeader = Request.Headers["Authorization"].ToString();  
            var authHeaderRegex = new Regex(@"BASIC (.*)");  
  
            if (!authHeaderRegex.IsMatch(authorizationHeader))  
            {  
                return await Task.FromResult(AuthenticateResult.Fail("Authorization code not formatted properly."));  
            }  
  
            var authBase64 = Encoding.UTF8.GetString(Convert.FromBase64String(authHeaderRegex.Replace(authorizationHeader, "$1")));  
            var authSplit = authBase64.Split(Convert.ToChar(":"), 2);  
            var authUsername = authSplit[0];  
            var authPassword = authSplit.Length > 1 ? authSplit[1] : throw new Exception("Unable to get password");  
  
            if (!_userValidate.Login(authUsername, authPassword))  
            {  
                return await Task.FromResult(AuthenticateResult.Fail("The username or password is not correct."));  
            }  
  
            var claims = new[] { new Claim("name", authUsername), new Claim(ClaimTypes.Role, "Admin") };  
            var identity = new ClaimsIdentity(claims, "BASIC");  
            var claimsPrincipal = new ClaimsPrincipal(identity);  
  
            return await Task.FromResult(AuthenticateResult.Success(new AuthenticationTicket(claimsPrincipal, Scheme.Name)));  
        }  
  
    }  

Program.cs:

using Microsoft.AspNetCore.Authentication;  
using Microsoft.EntityFrameworkCore;  
using OyunPalasGame.Data;  
using OyunPalasGame.Services;  
using OyunPalasGame.Services.Handlers;  
using OyunPalasGame.Services.Mapping;  
  
var builder = WebApplication.CreateBuilder(args);  
  
// Add services to the container.  
builder.Services.AddControllers();  
builder.Services.AddDbContext<OyunPalasDbContext>(  
    options => options.UseSqlServer("name=ConnectionStrings:OyunPalasDbContext"));  
builder.Services.AddTransient<IOyunPalasServices,OyunPalasServices>().AddTransient<UnitOfWork>();  
  
builder.Services.AddTransient<IUserValidate, UserValidate>();  
  
builder.Services.AddAuthentication("BasicAuthentication").  
    AddScheme<AuthenticationSchemeOptions, BasicAuthenticationHandler>  
        ("BasicAuthentication", null);  
  
builder.Services.AddAutoMapper(typeof(MappingProfile).Assembly);  
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle  
builder.Services.AddEndpointsApiExplorer();  
builder.Services.AddSwaggerGen();  
  
var app = builder.Build();  
  
// Configure the HTTP request pipeline.  
if (app.Environment.IsDevelopment())  
{  
    app.UseSwagger();  
    app.UseSwaggerUI();  
}  
  
app.UseRouting();  
  
//app.UseHttpsRedirection();  
  
app.UseAuthentication();  
app.UseAuthorization();  
  
app.MapControllers();  
  
app.Run();  

I tried without adding Authorization header in the Postman and I was supposed to get 401 but the service returned 200 OK. (I put [Authorize] to the controller)

Developer technologies ASP.NET ASP.NET Core
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.