Cuando un SSO falla, lo primero que hago es mirar qué viaja: el JWT que emitió Entra ID, la respuesta SAML que le llegó a la aplicación, el filtro LDAP que arma el conector. Para eso hay decodificadores online de sobra. El tema es que lo que pegás ahí suele ser un token válido o una aserción con datos de usuarios reales, y no tengo forma de saber qué hace esa página con eso.
Así que armé las mías. Se llaman Identity Tools, están publicadas en mi dominio y corren enteras en el navegador. No hay backend, no hay analytics, y la página tiene bloqueado a nivel navegador mandar datos a cualquier lado.
Qué hay hoy
Son seis herramientas, todas para cosas que me toca resolver seguido:
- Decodificador y verificador de JWT: header, claims, ventana de validez y advertencias. Verifica la firma con secreto HMAC, clave pública PEM, certificado, JWK o JWKS, y reconoce los tokens de Entra ID (emisor v1 o v2,
tid,oid, audiencia de Graph). - Decodificador SAML: toma un SAMLRequest o SAMLResponse del binding POST o Redirect (base64, deflate, URL encodeada o la URL completa) y muestra resumen, atributos, algoritmos de firma y el XML ordenado. También hace el camino inverso.
- Inspector de metadata SAML: entityID, endpoints por binding, formatos de NameID, certificados con thumbprint y vencimiento, y avisos de configuración.
- Validador de filtros LDAP: parser según RFC 4515 que marca la posición del error, explica el filtro en castellano (reglas bitwise,
IN_CHAIN, flags de AD) y genera el comando para PowerShell y ldapsearch. - Calculadora de userAccountControl: decodifica o arma el valor, marca los bits riesgosos y genera el filtro LDAP.
- Conversor de timestamps de AD: FILETIME, Generalized Time, Unix e ISO, intervalos como
maxPwdAgey filtros para cuentas inactivas.
Están en castellano y en inglés, con el mismo diseño que esta web (si elegiste el tema oscuro acá, allá también lo vas a ver oscuro).
Cómo me aseguro de que nada salga del navegador
Decir "no guardamos nada" es fácil. Quería algo que se pudiera comprobar, así que en el build cada página recibe una Content-Security-Policy como esta:
default-src 'none';
script-src 'self' 'sha256-...'; # solo mis scripts y los inline con hash conocido
style-src 'self' https://fonts.googleapis.com https://cdnjs.cloudflare.com;
font-src https://fonts.gstatic.com https://cdnjs.cloudflare.com;
img-src 'self' data:;
connect-src 'none'; # ni fetch, ni XHR, ni WebSocket
base-uri 'none';
form-action 'none' # ningún formulario puede enviarse
La línea que importa es connect-src 'none'. Con eso el navegador rechaza
cualquier fetch, XHR o WebSocket que intente hacer la página, aunque un
script lo pida. Y como script-src solo acepta mis archivos y los scripts
inline cuyo hash calculo en el build, tampoco se puede colar código de otro lado. Si
querés comprobarlo, abrí las DevTools en la pestaña de red, pegá un token y mirá: no sale
ningún request.
Hay un detalle que vale aclarar: la página sí carga tipografías e íconos desde Google Fonts y cdnjs. Eso son descargas de archivos estáticos; lo que pegás en las herramientas no viaja en ninguna.
Lo que fui metiendo en las explicaciones
Decodificar es la parte fácil. Lo que más tiempo me llevó fue que cada herramienta explique lo que muestra, porque ahí es donde se suele trabar un troubleshooting. Algunos ejemplos de lo que quedó adentro:
El verificador de JWT avisa si el algoritmo es simétrico (HS256 y compañía), porque quien
puede verificar ese token también puede emitir uno. También avisa si el header trae su
propia clave en jwk o apunta a una URL con jku o
x5u, que son caminos conocidos para que un verificador mal hecho acepte
tokens falsos.
El conversor de timestamps aclara algo que confunde a mucha gente:
lastLogonTimestamp se replica entre controladores de dominio, pero solo se
actualiza cuando el valor guardado es más viejo que
ms-DS-Logon-Time-Sync-Interval (14 días por defecto, menos un aleatorio de
hasta 5). Sirve para encontrar cuentas que no se usan hace meses; para saber si alguien
entró hoy, no.
Cómo está hecho
Es HTML y JavaScript sin frameworks, armado con Vite, igual que esta web. Lo más pesado fue escribir a mano lo que normalmente resolvería una librería: un parser de DER para leer los certificados X.509 que vienen en la metadata SAML y en los JWKS, y un parser de filtros LDAP que siga la RFC 4515 y diga en qué carácter está el error. Las firmas de JWT se verifican con Web Crypto, la API criptográfica que ya trae el navegador.
El código es público, con licencia MIT, en github.com/D4rkDr4gon/identity-tools. Si encontrás un token o una metadata que alguna herramienta lee mal, me sirve muchísimo que me lo cuentes (sin el dato sensible, obvio).
Las uso en mi trabajo, así que van a ir creciendo a medida que me cruce con cosas que hoy resuelvo a mano.