Caducidad de JWT no funciona cuando se utiliza la fecha de caducidad en UTC

Ujjwal Jung Thapa:

Estoy utilizando jjwtpara la creación de token de JWT. Todo funciona bien al establecer la fecha de caducidad con el tiempo del sistema local, es decir,

Fecha EXPDATE = new Date (new Date () getTime () + 180,000.); //java.util.Date

Pero he intentado usar la hora UTC formato de fecha y firmado el token de JWT con 3 min misma fecha de caducidad. Y ahora se está lanzando ExpiredJwtExceptionaunque incluso estoy validando tan pronto como la creación de la ficha. Estoy usando SimpleDateFormat para establecer zona horaria a UTC. Este es mi código para crear testigo usando jjwt en Java:

    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date expDate, issDate;
    try {
        expDate = (Date) simpleDateFormat.parse(sdf.format(new Date().getTime() + 180000));
        issDate = (Date) simpleDateFormat.parse(sdf.format(new Date().getTime()));
        JwtBuilder builder = Jwts.builder()
                .setExpiration(expDate)
                .setIssuedAt(issDate)
                .setId(id)
                .signWith(signingKey, signatureAlgorithm);
        jwtToken = builder.compact();
    } catch (ParseException ex) {
    }

El token se ha creado correctamente. Puedo verificar el contenido en línea también. EXPDATE es 3 min antes de issDate. También hago un llamado método para verificar el token tan pronto como después de que se crea al pasar que creó token. Mi método de verificación tiene:

    try {
        Jwts.parser().setSigningKey(signingKey).parseClaimsJws(token);
        log.info("jwt verification success");
    } catch (ExpiredJwtException exJwt) {
        log.info("expired jwt : \n{}", exJwt.getMessage());
    } catch (JwtException e) {
        log.info("tampered jwt");
    }

Pero me estoy haciendo ExpiredJwtException. El error es

JWT expirado JWT expiró a 2019-05-17T01: 24: 48Z. Hora: 2019-05-17T07: 06: 48Z, una diferencia de 20520836 milisegundos. reloj permite sesgar: 0 milisegundos.

Desde mi registro, la fecha de caducidad y la fecha de emisión en mi símbolo en este momento es:

issued date is: 2019-05-17T07:06:48.000+0545
expiry date is: 2019-05-17T07:09:48.000+0545

¿Cómo ocurre esto? Y gracias por su ayuda.

cassiomolin:

No hay necesidad de que SimpleDateFormataquí, ya que Daterepresenta el número de milisegundos desde la época Unix , es decir, la medianoche del 1 de enero 1970 (UTC).

Lo que puede causar confusión , sin embargo, es el toString()método, tal como se aplica la zona horaria predeterminada de la JVM cuando se genera una cadena que representa ese valor.

Como usted está preocupado por UTC, permítanme llamar su atención sobre lo que el Tiempo Universal Coordinado (UTC), en realidad es: Es un estándar de tiempo (y no una zona horaria ) y está determinada por los relojes atómicos de alta precisión combinada con la rotación de la Tierra.

El estándar de tiempo UTC se ajustó varias veces hasta 1972, cuando los segundos intercalares se introdujeron a mantener la hora UTC en línea con la rotación de la Tierra, lo cual no es del todo aún, y menos exactos que los relojes atómicos. A medida que la rotación de la Tierra se está desacelerando, de vez en cuando tenemos que insertar saltos de segundos aquí y allá:

Un gráfico de xkcd documentar la guerra entre cronometradores y tiempo

Mientras que el valor interno de Datepretende reflejar UTC, no puede hacerlo con exactitud debido a esos segundos intercalares.

Java 8 y la nueva API para la fecha y la hora

A pesar de que Datese adapte a sus necesidades cuando se trata de UTC, se debe evitar la misma. Es una clase de herencia ahora.

Java 8 introdujo una nueva API para las fechas, horas y duraciones instantes basado en el sistema de calendario ISO. El equivalente más cercano a Datedecir Instantque representa una marca de tiempo, un momento en la línea de tiempo en UTC.

Para capturar el momento actual en GMT, puede utilizar la siguiente:

Instant.now();              // Capture the current moment in UTC

Y se puede utilizar el siguiente para obtener una cadena que representa dicho valor:

Instant.now().toString();   // 2019-05-17T12:50:40.474Z

Esta cadena está formateada de acuerdo al ISO 8601 , donde Zindica que el tiempo dado es en UTC.

La interoperabilidad con JJWT

Para la interoperabilidad con JJWT, que no es compatible con los java.timetipos sin embargo, puede crear una instancia de Datepartir Instant:

Date.from(Instant.now());   // Convert from modern class to legacy class

Y aquí está una prueba que muestra cómo puede emitir y validar un token:

@Test
public void shouldMatchIssuedAtAndExpiration() {

    Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);

    Instant issuedAt = Instant.now().truncatedTo(ChronoUnit.SECONDS);
    Instant expiration = issuedAt.plus(3, ChronoUnit.MINUTES);

    log.info("Issued at: {}", issuedAt);
    log.info("Expires at: {}", expiration);

    String jws = Jwts.builder()
            .setIssuedAt(Date.from(issuedAt))
            .setExpiration(Date.from(expiration))
            .signWith(key)
            .compact();

    Claims claims = Jwts.parser()
            .setSigningKey(key)
            .parseClaimsJws(jws)
            .getBody();

    assertThat(claims.getIssuedAt().toInstant(), is(issuedAt));
    assertThat(claims.getExpiration().toInstant(), is(expiration));
}

Para el ejemplo anterior, he utilizado JJWT 0.10.5 con las dependencias que figuran en la documentación . En caso de que necesite, el código anterior fue escrito con las siguientes importafirmaciones:

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.security.Key;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.temporal.ChronoUnit;
import java.util.Date;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=186085&siteId=1
Recomendado
Clasificación