asp.net-core - route - select asp-for asp-items
Autenticación básica en ASP.NET Core (3)
ASP.NET Core 2.0 introdujo cambios de última hora en Autenticación e Identidad.
En 1.x, los proveedores de autenticación se configuraron a través de Middleware (como la implementación de la respuesta aceptada). En 2.0 está basado en servicios.
Detalles en MS doc: https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/identity-2x
Escribí una implementación de Autenticación básica para ASP.NET Core 2.0 y la publiqué en NuGet: https://github.com/bruno-garcia/Bazinga.AspNetCore.Authentication.Basic
Pregunta
¿Cómo puedo implementar la Autenticación básica con membresía personalizada en una aplicación web ASP.NET Core?
Notas
En MVC 5 estaba usando las instrucciones de este artículo que requieren agregar un módulo en
WebConfig
.Todavía estoy implementando mi nueva aplicación
MVC Core
enIIS
pero este enfoque parece no funcionar.Tampoco quiero utilizar el soporte integrado de IIS para la autenticación básica, ya que usa las credenciales de Windows.
ASP.NET Security no incluirá middleware de Autenticación Básica debido a su potencial inseguridad y problemas de rendimiento.
Si necesita middleware de Autenticación Básica para realizar pruebas, consulte https://github.com/blowdart/idunno.Authentication
Implementamos la seguridad Digest para un servicio interno mediante el uso de un ActionFilter:
public class DigestAuthenticationFilterAttribute : ActionFilterAttribute
{
private const string AUTH_HEADER_NAME = "Authorization";
private const string AUTH_METHOD_NAME = "Digest ";
private AuthenticationSettings _settings;
public DigestAuthenticationFilterAttribute(IOptions<AuthenticationSettings> settings)
{
_settings = settings.Value;
}
public override void OnActionExecuting(ActionExecutingContext context)
{
ValidateSecureChannel(context?.HttpContext?.Request);
ValidateAuthenticationHeaders(context?.HttpContext?.Request);
base.OnActionExecuting(context);
}
private void ValidateSecureChannel(HttpRequest request)
{
if (_settings.RequireSSL && !request.IsHttps)
{
throw new AuthenticationException("This service must be called using HTTPS");
}
}
private void ValidateAuthenticationHeaders(HttpRequest request)
{
string authHeader = GetRequestAuthorizationHeaderValue(request);
string digest = (authHeader != null && authHeader.StartsWith(AUTH_METHOD_NAME)) ? authHeader.Substring(AUTH_METHOD_NAME.Length) : null;
if (string.IsNullOrEmpty(digest))
{
throw new AuthenticationException("You must send your credentials using Authorization header");
}
if (digest != CalculateSHA1($"{_settings.UserName}:{_settings.Password}"))
{
throw new AuthenticationException("Invalid credentials");
}
}
private string GetRequestAuthorizationHeaderValue(HttpRequest request)
{
return request.Headers.Keys.Contains(AUTH_HEADER_NAME) ? request.Headers[AUTH_HEADER_NAME].First() : null;
}
public static string CalculateSHA1(string text)
{
var sha1 = System.Security.Cryptography.SHA1.Create();
var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(text));
return Convert.ToBase64String(hash);
}
}
Luego puede anotar los controladores o métodos a los que desea acceder con Digest Security:
[Route("api/xxxx")]
[ServiceFilter(typeof(DigestAuthenticationFilterAttribute))]
public class MyController : Controller
{
[HttpGet]
public string Get()
{
return "HELLO";
}
}
Para implementar la seguridad básica, simplemente cambie DigestAuthenticationFilterAttribute para no usar SHA1, pero dirija la decodificación Base64 del encabezado Authorization.