DS.Foundation.Authentication.AspNetCore
8.4.3
dotnet add package DS.Foundation.Authentication.AspNetCore --version 8.4.3
NuGet\Install-Package DS.Foundation.Authentication.AspNetCore -Version 8.4.3
<PackageReference Include="DS.Foundation.Authentication.AspNetCore" Version="8.4.3" />
<PackageVersion Include="DS.Foundation.Authentication.AspNetCore" Version="8.4.3" />
<PackageReference Include="DS.Foundation.Authentication.AspNetCore" />
paket add DS.Foundation.Authentication.AspNetCore --version 8.4.3
#r "nuget: DS.Foundation.Authentication.AspNetCore, 8.4.3"
#:package DS.Foundation.Authentication.AspNetCore@8.4.3
#addin nuget:?package=DS.Foundation.Authentication.AspNetCore&version=8.4.3
#tool nuget:?package=DS.Foundation.Authentication.AspNetCore&version=8.4.3
DS.Foundation.Authentication.AspNetCore
Protege APIs ASP.NET Core con JWT Bearer emitidos por DS.Foundation.Authentication (por ejemplo desde DS.Security) y con API keys en el encabezado X-Api-Key. Inyecta el usuario autenticado como UserToken.
- Target framework:
net8.0. - Dependencias:
DS.Foundation.Authentication,Microsoft.AspNetCore.Authentication.JwtBearer8.x y los paquetesMicrosoft.IdentityModel.*/System.IdentityModel.Tokens.Jwten 8.2.1.
Instalación
<PackageReference Include="DS.Foundation.Authentication.AspNetCore" Version="8.4.3" />
Trae DS.Foundation.Authentication como dependencia. Si la aplicación también lo referencia en forma directa, use la misma versión.
Todos los paquetes Microsoft.IdentityModel.* y System.IdentityModel.Tokens.Jwt deben quedar en la misma versión: Microsoft no soporta mezclarlas, y una mezcla falla recién en tiempo de ejecución (MissingMethodException, TypeLoadException o tokens rechazados con errores IDX...). Si la aplicación agrega otro paquete que trae alguno de ellos (por ejemplo, Microsoft.Identity.Web), referencie en forma directa la versión más alta para alinearlos todos.
Registro
using DS.Foundation.Authentication.ApiKeyAuthentication;
using DS.Foundation.Authentication.JwtBearerAuthentication;
builder.Services.AddJwtBearerAuthentication(builder.Configuration); // valida la configuración JWT al arrancar
builder.Services.AddJwtBearerAuthorization(builder.Configuration); // política por defecto: usuario autenticado por JwtBearer
builder.Services.AddApiKeyAuthentication(); // solo si usa [ApiKey]
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapControllers().RequireAuthorization();
AddJwtBearerAuthentication:
- Llama a
AddJwtAuthentication, validaSystem:Authentication:Jwty lanza una excepción en el arranque si falta algún dato. - Registra el esquema
JwtBearerDefaults.AuthenticationSchemecon los parámetros deJwtTokenValidation.CreateValidationParameters: firma, emisor (cualquiera deIssueryValidIssuers), audiencia, expiración y algoritmo (solo HMAC-SHA256). - Registra
IHttpContextAccessory unUserTokenscoped construido desdeHttpContext.User. Esnullcuando el request no está autenticado.
UseJwtBearerAuthorization(IApplicationBuilder, IConfiguration) solo llama a UseAuthorization(); se mantiene por compatibilidad. UseAuthentication() siempre va antes de UseAuthorization().
Configuración
Usa la sección System:Authentication:Jwt descripta en el README de DS.Foundation.Authentication (Issuer, ValidIssuers, Audience, SecretKey de al menos 32 bytes, TokenLifetimeMinutes, ClockSkewSeconds).
Emisores aceptados
El pipeline acepta tokens cuyo iss sea Issuer o cualquier entrada de ValidIssuers, sin configuración extra. Hace falta al menos una de las dos claves; si no, AddJwtBearerAuthentication lanza InvalidOperationException: System:Authentication:Jwt:Issuer or System:Authentication:Jwt:ValidIssuers is required. al arrancar. La comparación es exacta y distingue mayúsculas; un emisor no aceptado recibe 401.
{
"System": {
"Authentication": {
"Jwt": {
"Issuer": "DS.Security",
"ValidIssuers": [ "https://security.example.com" ],
"Audience": "mi-sistema"
}
}
}
}
System__Authentication__Jwt__Issuer=DS.Security
System__Authentication__Jwt__ValidIssuers__0=https://security.example.com
Una aplicación configurada solo con Issuer funciona igual que antes. Una configurada solo con ValidIssuers necesita 8.4.3 o posterior de este paquete (trae DS.Foundation.Authentication 8.4.1): las versiones anteriores exigen Issuer y fallan al arrancar.
Para cambiar el emisor de los tokens: primero actualice el paquete y agregue el emisor nuevo a ValidIssuers en todas las aplicaciones y despliéguelas; recién después DS.Security empieza a emitir con ese emisor. El procedimiento completo está en el README de DS.Foundation.Authentication ("Cambiar el emisor de los tokens").
Otras claves
| Clave | Tipo | Valor por defecto | Obligatoria |
|---|---|---|---|
System:Authentication:Jwt:RequireHttpsMetadata |
bool |
true |
No |
System:ApiKey |
string |
sin valor | Sí si usa [ApiKey]: sin valor, todos los requests reciben 401 |
Uso
Endpoint protegido con JWT
[ApiController]
[Route("api/pedidos")]
public class PedidosController : ControllerBase
{
private readonly UserToken _usuario;
public PedidosController(UserToken usuario) => _usuario = usuario;
[HttpGet]
public IActionResult Get() => Ok(new { _usuario.Username, _usuario.TenantCode });
}
El cliente envía Authorization: Bearer <jwt>.
Endpoint protegido con API key
[ApiKey]
[AllowAnonymous] // si la política por defecto exige JWT y este endpoint solo usa API key
[HttpPost("webhook")]
public IActionResult Webhook() => Ok();
El cliente envía X-Api-Key: <clave>. Si falta o no coincide con System:ApiKey, la respuesta es 401.
Errores frecuentes
| Síntoma | Causa | Solución |
|---|---|---|
InvalidOperationException al arrancar (... is required o ... at least 32 bytes) |
Configuración JWT incompleta | Completar System:Authentication:Jwt |
| 401 con un token emitido por DS.Security | El iss del token no está en Issuer ni en ValidIssuers (se compara exacto, con mayúsculas), Audience o SecretKey distintos a los del emisor, o token vencido |
Agregar el emisor a ValidIssuers y usar la misma Audience y SecretKey que el emisor |
InvalidOperationException: ...:Issuer is required. con solo ValidIssuers configurado |
Versión anterior a 8.4.3 | Actualizar el paquete |
UserToken es null en el controlador |
El endpoint permite anónimos o falta UseAuthentication() |
Exigir autorización y respetar el orden del pipeline |
InvalidOperationException: No service for type 'ApiKeyAuthorizationFilter' |
Se usó [ApiKey] sin registrar el filtro |
Llamar a AddApiKeyAuthentication() |
401 en todos los endpoints [ApiKey] |
System:ApiKey vacía |
Configurar la clave |
Qué no hacer
- No usar
UseJwtBearerAuthorization(WebApplication, IConfiguration): está obsoleto. UseUseAuthorization()yMapControllers().RequireAuthorization(). - No leer el encabezado
Authorizationa mano para obtener el usuario: inyecteUserTokeno useHttpContext.User. - No usar
GetCurrentJwt(HttpRequest)deOmniLayerCookieService: devuelve siempre una cadena vacía. - No guardar
SecretKeyniSystem:ApiKeyenappsettings.jsonversionado.
Cambios
Ver CHANGELOG.md.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net8.0
- DS.Foundation.Authentication (>= 8.4.1)
- Microsoft.AspNetCore.Authentication.JwtBearer (>= 8.0.32)
- Microsoft.IdentityModel.Protocols.OpenIdConnect (>= 8.2.1)
- System.IdentityModel.Tokens.Jwt (>= 8.2.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.