Middleware para autenticación básica en .NET
Clase 12 de 21 • Curso de APIs con .NET
Contenido del curso
Estructura de una Web API
- 7

Configuración CORS en .NET: solución al error
07:08 min - 8

Rutas en APIs .NET con parámetros
12:50 min - 9

Documentación de APIs con OpenAPI y Swagger en .NET
14:25 min - 10

Middlewares en ASP.NET: pipeline y custom middleware
10:32 min - 11

Inyección de dependencias en .NET: ILogger
09:18 min - 12

Middleware para autenticación básica en .NET
Viendo ahora
Arquitectura y Middlewares
- 13

Configuración de Entity Framework Core en .NET
07:31 min - 14

Modelos C# y relaciones con Entity Framework
10:01 min - 15

Servicios con Entity Framework para ASP.NET
13:51 min - 16

Cómo crear controladores API en .NET
14:47 min - 17

Conectar API .NET con PostgreSQL
06:57 min - 18

Conectar API .NET a PostgreSQL con EF Core
06:57 min - 19

Clean Architecture en .NET APIs escalables
09:08 min - 20

Pruebas unitarias con xUnit, InMemory y Copilot
09:05 min - 21

Qué sigue después de tu API con .NET
02:16 min
La autenticación es la primera barrera de seguridad en una API. Aquí verás cómo activar autenticación básica con usuario y contraseña codificados en Base64 usando un middleware en .NET, cómo evitar errores 401 al probar con Swagger y Postman, y qué ajustes aplicar en OpenAPI para enviar credenciales desde la documentación. Todo con un enfoque práctico y directo.
¿Cómo implementar autenticación básica con middleware en .NET?
La idea central es crear una clase llamada BasicAuthMiddleware.cs que intercepte cada request, valide el encabezado de autorización y, si las credenciales son correctas, permita continuar con el siguiente componente del pipeline.
- El middleware controla el acceso a los endpoints mediante usuario y contraseña en Base64.
- Se excluyen rutas de documentación como Swagger, Scalar y OpenAPI para poder usar la interfaz de pruebas.
- Si faltan credenciales o no coinciden, se responde con 401 (Unauthorized) según el patrón REST.
- Mejora sugerida: mover usuario y contraseña a appsettings y considerar cifrado, en lugar de “quemarlas” en el código.
¿Qué hace la clase BasicAuthMiddleware.cs?
La clase define dos valores para usuario y contraseña, recibe el request delegate (el next) y, en su InvokeAsync, ejecuta la lógica de autenticación. Si pasa, llama al siguiente middleware; si no, devuelve 401.
// BasicAuthMiddleware.cs (estructura simplificada)
public class BasicAuthMiddleware
{
private readonly RequestDelegate _next;
private readonly string _user = "<usuario>";
private readonly string _password = "<contraseña>";
public BasicAuthMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
var path = context.Request.Path.Value ?? string.Empty;
// Omitir Swagger/Scalar/OpenAPI para poder usar la documentación
if (path.Contains("swagger", StringComparison.OrdinalIgnoreCase) ||
path.Contains("scalar", StringComparison.OrdinalIgnoreCase) ||
path.Contains("openapi", StringComparison.OrdinalIgnoreCase))
{
await _next(context);
return;
}
if (!context.Request.Headers.TryGetValue("Authorization", out var header) ||
!header.ToString().StartsWith("Basic ", StringComparison.OrdinalIgnoreCase))
{
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
return;
}
var token = header.ToString().Substring("Basic ".Length).Trim();
var decoded = Encoding.UTF8.GetString(Convert.FromBase64String(token));
var parts = decoded.Split(':', 2);
var user = parts.ElementAtOrDefault(0);
var pass = parts.ElementAtOrDefault(1);
if (user == _user && pass == _password)
await _next(context);
else
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
}
}
public static class BasicAuthExtensions
{
public static IApplicationBuilder UseBasicAuth(this IApplicationBuilder app)
=> app.UseMiddleware<BasicAuthMiddleware>();
}
¿En qué orden va en el pipeline de middlewares?
La autenticación debe ejecutarse antes de la autorización. Se registra el middleware con el método de extensión para asegurar el orden correcto.
// Program.cs (fragmento ilustrativo)
var app = builder.Build();
// Primero autenticación
app.UseBasicAuth();
// Luego autorización si aplica
// app.UseAuthorization();
app.Run();
¿Cómo probar con Swagger y Postman sin errores 401?
Inicialmente, al usar el botón Try it out en Swagger, verás 401 porque la UI no envía credenciales. En Postman, selecciona Basic Auth en Authorization, ingresa el usuario y la contraseña, y la API responde correctamente. En el ejemplo, se usaron credenciales “Plaxy” y “12345” para validar que la autenticación funciona.
- En Postman, usa Basic Auth y envía usuario y contraseña.
- En Swagger, habilita el botón Authorize añadiendo el esquema de seguridad basic en OpenAPI.
- Marca el esquema como requirement para que el encabezado Authorization se incluya en los requests.
¿Cómo habilitar Basic Auth en Swagger con OpenAPI?
Se agrega una definición de seguridad tipo http con esquema "basic" y un requirement para que Swagger envíe el encabezado en cada request.
// Program.cs (configuración de Swagger/OpenAPI)
builder.Services.AddSwaggerGen(c =>
{
c.AddSecurityDefinition("basic", new OpenApiSecurityScheme
{
Name = "Authorization",
Type = SecuritySchemeType.Http,
Scheme = "basic",
In = ParameterLocation.Header,
Description = "Usuario y contraseña con *Basic Auth*."
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "basic"
}
},
Array.Empty<string>()
}
});
});
¿Qué buenas prácticas y siguientes pasos recomienda el instructor?
Aunque este enfoque brinda un mínimo de seguridad, no es recomendado para producción.
- Para producción, usar JSON Web Token, OAuth2, Identity, Microsoft Entra o Cognito.
- Centralizar credenciales en appsettings y evaluar cifrado en reposo.
- Verificar que todos los endpoints devuelvan 401 si no se envían credenciales, ya sea desde Scalar, Swagger o Postman.
- Añadir soporte similar en Scalar y, si se desea, precargar usuario y contraseña para agilizar pruebas.
- Mantener el orden: autenticación antes de autorización en el pipeline.
¿Te quedó alguna duda o quieres compartir tu implementación con Basic Auth y Swagger? Comenta tus preguntas y hallazgos para seguir mejorando juntos.