Hello there,
I implemented a basic authentication handler. I debugged it, and even though it enters
I tried without adding the Authorization header in the Postman and I was supposed to get 401 but the service returned 200 OK. (I put
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 the Authorization header in the Postman and I was supposed to get 401 but the service returned 200 OK. (I put
[Authorize]
to the controller)