I have an ASP.NET Core 2.1 Web API project that targets .NET Framework 4.6.2 and now I need to add Basic Authentication to it. Before anyone is asking, I need to target .NET Framework 4.6.2 because I am still using EntityFramework 6 (we have a database-first approach for our repo and I need the EDMX model).
There are several examples found on the Internet, but they all rely on AddAuthentication method of the IServiceCollection object that gets injected. Perhaps because of the .NET Core/.NET Framework combo that I have, in my case that method is not available. Instead I have AddAuthenticationCore which has a different signature. I couldn't find any examples for the AddAuthenticationCode method. Can anyone help?
Thanks,
Ed
Edit:
I found some information about this AddAuthenticationCore and with the help of the documentation, I added this in the ConfigureServices method:
// add basic authentication
services.AddAuthenticationCore(options =>
{
options.AddScheme<BasicAuthenticationHandler>("BasicAuthentication", null);
options.DefaultAuthenticateScheme = "BasicAuthentication";
});
My BasicAuthenticationHandler class is decalred like this:
public class BasicAuthenticationHandler : IAuthenticationHandler
{
private HttpContext _context;
public Task<AuthenticateResult> AuthenticateAsync()
{
if(_context.Request.Headers.ContainsKey("Authorization"))
{
return Task.FromResult(AuthenticateResult.Fail("Missing Authorization Header."));
}
try
{
var authHeader = AuthenticationHeaderValue.Parse(_context.Request.Headers["Authorization"]);
var credentialBytes = Convert.FromBase64String(authHeader.Parameter);
var credentials = Encoding.UTF8.GetString(credentialBytes).Split(':');
var username = credentials[0];
var password = credentials[1];
if(username.Equals("My_User") && password.Equals("MyPassword"))
{
var claims = new[] {
new Claim("UserId", username),
new Claim("UserName", username),
};
var identity = new ClaimsIdentity(claims, "BasicAuthentication");
var principal = new ClaimsPrincipal(identity);
var ticket = new AuthenticationTicket(principal, "BasicAuthenticationScheme");
return Task.FromResult(AuthenticateResult.Success(ticket));
}
else
{
return Task.FromResult(AuthenticateResult.Fail("Invalid User Name or Password"));
}
}
catch
{
return Task.FromResult(AuthenticateResult.Fail("Invalid Authorization Header"));
}
}
public Task ChallengeAsync(AuthenticationProperties properties)
{
throw new NotImplementedException();
}
public Task ForbidAsync(AuthenticationProperties properties)
{
throw new NotImplementedException();
}
public Task InitializeAsync(AuthenticationScheme scheme, HttpContext context)
{
_context = context;
return Task.FromResult<object>(null);
}
}
I have break points in both the InitializeAsync and AuthenticateAsync but none of these are called. My calls are successful even when the Autorization header contains the wrong password. Any idea why my Basic Authentication handler is ineffective?
There are similar questions here whose answers suggest that UseAuthentication must be called inside Configure. The problem is that I do not have access to that method:
question from:
https://stackoverflow.com/questions/65910955/adding-basicauthentication-to-an-asp-net-core-2-1-web-api-project 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…