Estado
Implementado y verificado localmente. La verificación de ida y vuelta contra un IdP real (obtención de JWKS, firma/verificación de tokens contra una instancia XID en producción) aún no se ha realizado y debe completarse antes del uso en producción.
Instalación
Se requieren Java 17+ y Maven.
<dependency>
<groupId>dev.xid</groupId>
<artifactId>xid-sdk-java</artifactId>
<version>0.1.0-SNAPSHOT</version>
</dependency>Inicio rápido
Construye un único XidClient al arrancar la aplicación y úsalo como singleton.
import dev.xid.sdk.XidClient;
import dev.xid.sdk.XidClientOptions;
import dev.xid.sdk.XidClaims;
import dev.xid.sdk.XidTokenException;
import dev.xid.sdk.XidJwksException;
XidClient xid = XidClient.create(
XidClientOptions.builder()
.issuer("https://xid.dev")
.audience("your-client-id")
.webhookSecret("whsec_xxx")
.build()
);
try {
XidClaims claims = xid.verifyToken(accessToken);
String userId = claims.getSub();
String scope = claims.getScope();
} catch (XidTokenException e) {
response.sendError(401, "Unauthorized: " + e.getReason());
} catch (XidJwksException e) {
response.sendError(503, "Service unavailable");
}Autenticar una solicitud HTTP
import dev.xid.sdk.AuthResult;
// Option A: pass Authorization header value directly
AuthResult result = xid.authenticateRequest(authHeader, null);
// Option B: pass a headers Map (Spring MVC example)
Map<String, String> headers = Collections.list(request.getHeaderNames())
.stream()
.collect(Collectors.toMap(h -> h, request::getHeader));
AuthResult result = xid.authenticateRequest(headers);
if (result.isAuthenticated()) {
String userId = result.getClaims().get().getSub();
} else {
response.sendError(401);
}Verificar webhook
import dev.xid.sdk.XidWebhookException;
byte[] rawBody = request.getInputStream().readAllBytes();
Map<String, String> headers = Map.of(
"svix-id", request.getHeader("svix-id"),
"svix-timestamp", request.getHeader("svix-timestamp"),
"svix-signature", request.getHeader("svix-signature")
);
try {
xid.verifyWebhook(headers, rawBody);
} catch (XidWebhookException e) {
response.sendError(400, "Invalid webhook: " + e.getReason());
}XidClientOptions
| Método | Por defecto | Descripción |
|---|---|---|
.issuer(String) |
obligatorio | Emisor OIDC; debe coincidir exactamente con el iss del token |
.audience(String) |
null |
aud esperado; null omite la validación |
.webhookSecret(String) |
null |
Secreto del webhook (prefijo whsec_ o base64 sin prefijo) |
.jwksCacheDuration(Duration) |
1 hora | TTL del caché en memoria de JWKS |
.clockSkewTolerance(Duration) |
30 segundos | tolerancia de desfase de reloj para exp/nbf |
.connectTimeout(Duration) |
5 segundos | Tiempo de espera de conexión HTTP para obtener el JWKS |
.readTimeout(Duration) |
10 segundos | Tiempo de espera de lectura HTTP para obtener el JWKS |
Notas de plataforma
- Usa
nimbus-jose-jwtpara el análisis de JWT/JWKS. ES256 es el principal; RS256 y PS256 están soportados. - Todas las APIs públicas son sincrónicas y thread-safe.
- Registro mediante la fachada SLF4J; trae tu propia implementación (Logback, Log4j2).
- Jerarquía de excepciones:
XidException->XidTokenException,XidJwksException,XidWebhookException.