Showing posts with label Software Security. Show all posts
Showing posts with label Software Security. Show all posts

Sunday, January 26, 2025

OAuth2, OpenID Connect (OIDC) y JWT

Marco Teórico

OAuth2, OpenID Connect (OIDC), y JWT se combinan comúnmente porque juntos ofrecen una solución integral, segura y eficiente para autenticación y autorización en aplicaciones modernas. La razón de esta cambinación es la siguiente: 

  • Completo: OAuth2 + OIDC cubren tanto autorización como autenticación.
  • Eficiente: JWT permite transportar tokens de manera rápida y sin depender de almacenamiento adicional en el servidor.
  • Compatible: Es ampliamente utilizado en aplicaciones web, móviles y APIs debido a su facilidad de integración.

Poniéndolo en contexto con el esquema de la Seguridad Informática:


En el control de riesgos definimos las acciones, estrategias y mecanismos implementados para mitigar, minimizar o eliminar los riesgos identificados durante el análisis de riesgos. En función de la clásica combinación de estos estándares y mecanismos de seguridad para identidad y acceso (OAuth2, OIDC y JWT) podemos decir lo siguiente: 

  • Servicios de seguridad:  Requisitos generales que se necesitan para proteger la información.
    • Autenticación: Verificar que un usuario sea quien dice ser.
    • Autorización: Controlar qué recursos y acciones están permitidos para un usuario autenticado.
    • Confidencialidad: Proteger la información transmitida.
    • Integridad: Asegurar que los datos no sean manipulados en el proceso.
  • Mecanismos de seguridad: Formas concretas de implementar esos requisitos en la práctica.
    • OAuth2: Cómo se implementa la autorización mediante flujos como el Authorization Code Flow para delegar el acceso a recursos de manera segura.
    • OpenID Connect (OIDC): Cómo se implementa la autenticación mediante una extensión de OAuth2 que utiliza el ID Token para identificar al usuario.
    • JWT (JSON Web Token): Cómo se representa y transporta la información de manera segura mediante un token firmado digitalmente que asegura integridad y confidencialidad.

Implementación en .NET

Implementar OAuth2, OpenID Connect (OIDC) y JWT en un proyecto .NET implica integrar los conceptos de autenticación y autorización utilizando bibliotecas y configuraciones específicas. A continuación, vemos un ejemplo:

1. Configuración del Proveedor de Identidad

Primero necesitas un proveedor de identidad que soporte OAuth2 y OpenID Connect, como Azure AD, Auth0, Okta, Keycloak o Google.

Obtener Credenciales del Proveedor:
  • ID del Cliente (Client ID).
  • Secreto del Cliente (Client Secret).
  • URL de autorización y token (Authorization Endpoint, Token Endpoint).

2. Configuración del Proyecto en .NET

Usaremos ASP.NET Core para esta implementación.

a) Instalar paquetes necesarios:

dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
dotnet add package Microsoft.IdentityModel.Protocols.OpenIdConnect
dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect


b) Configurar los servicios en Program.cs o Startup.cs:
En el archivo Program.cs, añade los servicios para autenticación y validación de JWT.

builder.Services.AddAuthentication(options =>
{
    options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(options =>
{
    options.Authority = "https://<your-provider-domain>"; // URL del proveedor OIDC (p.ej., Auth0, Azure AD)
    options.Audience = "<your-audience>"; // Identificador del API configurado en el proveedor
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true
    };
});


c) Habilitar autenticación en el pipeline de la aplicación:

Agrega el middleware de autenticación en el pipeline:

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

app.MapControllers();
app.Run();


3. Proteger Endpoints en la API

Utiliza el atributo [Authorize] en los controladores o acciones específicas que requieren autenticación.

[ApiController]
[Route("api/[controller]")]
[Authorize] // Protege este endpoint
public class SecureController : ControllerBase
{
    [HttpGet]
    public IActionResult GetSecureData()
    {
        return Ok("This is a secure endpoint");
    }
}

4. Flujo de Autenticación y Autorización

  • El cliente (como una SPA o aplicación móvil) redirige al usuario al endpoint de autorización del proveedor.
  • Una vez autenticado, el proveedor devuelve:
    • Un ID Token (si usas OIDC) en formato JWT con información sobre el usuario.
    • Un Access Token (OAuth2) en formato JWT para acceder a los recursos de la API.
  • El cliente incluye el Access Token en las peticiones a la API:
Authorization: Bearer <access_token>
  • La API valida el token utilizando el middleware configurado.

5. Validar el Token JWT

El middleware de ASP.NET Core se encarga de la validación automáticamente. Sin embargo, si necesitas validarlo manualmente, puedes usar la biblioteca System.IdentityModel.Tokens.Jwt:

var handler = new JwtSecurityTokenHandler();
var token = handler.ReadJwtToken("<access_token>");
var claims = token.Claims; // Obtener claims del token


6. Flujo Adicional: OpenID Connect para Login

Si estás desarrollando una aplicación que necesita autenticación de usuario, puedes usar OpenIdConnect:

builder.Services.AddAuthentication(options =>
{
    options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
    options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie()
.AddOpenIdConnect(options =>
{
    options.Authority = "https://<your-provider-domain>";
    options.ClientId = "<your-client-id>";
    options.ClientSecret = "<your-client-secret>";
    options.ResponseType = OpenIdConnectResponseType.Code;
    options.SaveTokens = true;
    options.GetClaimsFromUserInfoEndpoint = true;
});

Esto permite iniciar sesión mediante el proveedor configurado.


Conclusión

La combinación de OAuth2, OIDC y JWT es muy popular porque equilibra seguridad, escalabilidad y compatibilidad con aplicaciones modernas. Sin embargo, dependiendo del caso de uso, puedes optar por tecnologías más simples (como API Keys o sesiones) o más avanzadas (como autenticación biométrica o blockchain).
  • Token-Based Authentication con Simple Tokens (Sin JWT): Utiliza tokens simples (generalmente UUIDs o cadenas aleatorias) en lugar de JWT. Estos tokens se almacenan en una base de datos en el servidor para validarlos. Ejemplo: Sesiones tradicionales usando cookies con un token de sesión generado.
  • API Key Authentication: Las aplicaciones utilizan claves API para autenticar solicitudes. Estas claves son secretas y se pasan en cada solicitud (por ejemplo, en la cabecera HTTP). Ejemplo: Uso de claves API en servicios como Google Maps o servicios REST.
  • LDAP (Lightweight Directory Access Protocol): Utilizado principalmente en entornos empresariales para autenticar usuarios a través de un directorio centralizado. Ejemplo: Aplicaciones internas en organizaciones que usan Active Directory.
  • SAML (Security Assertion Markup Language): Un estándar basado en XML utilizado para autenticación y autorización en aplicaciones empresariales. Ejemplo: Integraciones con servicios empresariales como Salesforce o aplicaciones on-premise.
  • Session-Based Authentication: Una técnica tradicional donde el servidor genera una sesión para el usuario después de autenticarse, y el cliente almacena un identificador de sesión (generalmente en una cookie). Ejemplo: Aplicaciones web que no utilizan APIs modernas.
  • Biometric Authentication: Utiliza características biométricas como huellas digitales, reconocimiento facial o escaneo de retina para autenticar al usuario. Ejemplo: Aplicaciones móviles con autenticación por huella digital (ej.: Face ID, Touch ID).
  • Passwordless Authentication: Elimina el uso de contraseñas y utiliza métodos alternativos como enlaces mágicos enviados por correo electrónico, códigos de verificación, o autenticación con dispositivos confiables. Ejemplo: Aplicaciones que envían un enlace para iniciar sesión (como Slack o Notion).
  • Blockchain-Based Authentication: Utiliza tecnologías de blockchain para verificar identidades descentralizadas y gestionar autorizaciones. Ejemplo: Identidades descentralizadas con proyectos como uPort o Sovrin.

¡Gracias por llegar hasta aquí!

Saturday, November 28, 2020

Meditaciones sobre seguridad de aplicaciones: explorando las bases

Hace poco tuve la oportunidad de asistir a una charla interesante sobre OAuth2, un mecanismo de autorización basado en un modelo de acceso por delegación. Más allá de cuan interesante fue la charla, lo que realmente me llamó la atención fue algo que dijo el expositor al principio:

La seguridad es a veces un tema complejo o árido de explicar.

Totalmente de acuerdo. Puede que esto sea una opinión rebatible, pero despertó mi curiosidad para explorar más sobre temas de seguridad de aplicaciones. Empecemos por las bases.

En mi trabajo como desarrollador, inevitablemente tengo lidiar con temas de seguridad: autenticación/autorización, hashing, encriptación, etc. Es decir, mis esfuerzos como desarrollador se orientan en implementar mecanismos para proteger datos y procesos computacionales de aplicaciones. Este me parece un buen inicio para seguir razonando sobre la seguridad.

No obstante, sé que mi visión de desarrollador sobre la seguridad puede ser acotada. Así que me gustaría dar un paso más explorando el concepto de la seguridad de la información según ISO 27001: 

La seguridad de la información consiste en la preservación de su confidencialidad, integridad y disponibilidad, así como de los sistemas implicados en su tratamiento, dentro de una organización.

ISO 27001:2013

En otras palabras, la información es segura o fiable cuando hay confidencialidad, integridad y disponibilidad. De esto se deduce que los ataques contra la seguridad de la información son ataques contra estos pilares.


¿Cómo proteger nuestra información contra los ataques? Existe un enfoque denominado defensa en profundidad el cual propone proteger la información a través de múltiples capas. 

Cada capa pone foco en las distintas áreas donde pueden ocurrir ataques. En cada una de estas se aplicarán diferentes controles de seguridad, tecnologías y funcionalidades. El conjunto de capas crea una protección profunda que complicará el trabajo del atacante para llegar a los procesos y datos.

Y para cerrar esta reflexión que va de lo particular a lo general, quisiera englobar todo lo anterior bajo el amplio concepto de Seguridad. Es interesante saber que existe la carrera en Ciencias de la Seguridad, la cual define la seguridad como:

Ciencia interdisciplinaria que está encargada de evaluar, estudiar y gestionar los riesgos que se encuentra sometido una persona, un bien o el ambiente.
Wikipedia

Una definición tan amplia como la vida misma. ¿Para qué evaluar, estudiar y gestionar los riesgos? Para reducirlos a niveles aceptables y así la persona, bien o ambiente pueda cumplir su misión.

Vaya, que amplio es todo esto. Creo que esta pequeña reflexión me sirvió para darme cuenta donde estoy parado respecto a la seguridad. Básicamente, mi trabajo se centra reducir los riesgos de que los atacantes hagan de las suyas rompiendo la integridad, confidencialidad y disponibilidad de datos y procesos de mis aplicaciones. Con esta conclusión creo que ya puedo cerrar este artículo y pensar en los próximos.

¡Gracias por llegar hasta aquí!