Search in sources :

Example 1 with PrematureJWTException

use of io.gravitee.am.common.exception.jwt.PrematureJWTException in project gravitee-access-management by gravitee-io.

the class DefaultJWTParser method parse.

@Override
public JWT parse(String payload) {
    try {
        // verify format
        SignedJWT signedJWT = SignedJWT.parse(payload);
        // verify signature
        boolean verified = signedJWT.verify(verifier);
        if (!verified) {
            throw new JOSEException("The signature was not verified");
        }
        Map<String, Object> claims = signedJWT.getPayload().toJSONObject().entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        JWT jwt = new JWT(claims);
        // verify exp and nbf values
        // https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-30#section-4.1.4
        // token MUST NOT be accepted on or after any specified exp time
        Instant now = Instant.now();
        evaluateExp(jwt.getExp(), now, this.allowedClockSkewMillis);
        // https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-30#section-4.1.5
        // token MUST NOT be accepted before any specified nbf time
        evaluateNbf(jwt.getNbf(), now, this.allowedClockSkewMillis);
        return jwt;
    } catch (ParseException ex) {
        logger.debug("The following JWT token : {} is malformed", payload);
        throw new MalformedJWTException("Token is malformed", ex);
    } catch (ExpiredJWTException ex) {
        logger.debug("The following JWT token : {} is expired", payload);
        throw new ExpiredJWTException("Token is expired", ex);
    } catch (PrematureJWTException ex) {
        logger.debug("The following JWT token : {} must not be accepted (nbf)", payload);
        throw new PrematureJWTException("Token must not be accepted (nbf)", ex);
    } catch (JOSEException ex) {
        logger.debug("Verifying JWT token signature : {} has failed", payload);
        throw new SignatureException("Token's signature is invalid", ex);
    } catch (Exception ex) {
        logger.error("An error occurs while parsing JWT token : {}", payload, ex);
        throw ex;
    }
}
Also used : JWT(io.gravitee.am.common.jwt.JWT) SignedJWT(com.nimbusds.jwt.SignedJWT) Instant(java.time.Instant) PrematureJWTException(io.gravitee.am.common.exception.jwt.PrematureJWTException) ExpiredJWTException(io.gravitee.am.common.exception.jwt.ExpiredJWTException) SignedJWT(com.nimbusds.jwt.SignedJWT) SignatureException(io.gravitee.am.common.exception.jwt.SignatureException) JOSEException(com.nimbusds.jose.JOSEException) MalformedJWTException(io.gravitee.am.common.exception.jwt.MalformedJWTException) ExpiredJWTException(io.gravitee.am.common.exception.jwt.ExpiredJWTException) PrematureJWTException(io.gravitee.am.common.exception.jwt.PrematureJWTException) InvalidKeyException(java.security.InvalidKeyException) SignatureException(io.gravitee.am.common.exception.jwt.SignatureException) ParseException(java.text.ParseException) MalformedJWTException(io.gravitee.am.common.exception.jwt.MalformedJWTException) ParseException(java.text.ParseException) JOSEException(com.nimbusds.jose.JOSEException) Map(java.util.Map)

Example 2 with PrematureJWTException

use of io.gravitee.am.common.exception.jwt.PrematureJWTException in project gravitee-access-management by gravitee-io.

the class AuthenticationRequestParseRequestObjectHandler method validateRequestObjectClaims.

private Single<JWT> validateRequestObjectClaims(RoutingContext context, JWT jwt) {
    try {
        OpenIDProviderMetadata oidcMeta = context.get(PROVIDER_METADATA_CONTEXT_KEY);
        Client client = context.get(CLIENT_CONTEXT_KEY);
        final JWTClaimsSet claims = jwt.getJWTClaimsSet();
        // aud : The Audience claim MUST contain the value of the Issuer Identifier for the OP, which identifies the Authorization Server as an intended audience.
        final Object aud = claims.getClaim(Claims.aud);
        if (aud == null || (aud instanceof String && !oidcMeta.getIssuer().equals(aud)) || (aud instanceof Collection && (((Collection) aud).isEmpty() || !((Collection) aud).stream().anyMatch(oidcMeta.getIssuer()::equals)))) {
            return Single.error(new InvalidRequestException("aud is missing or invalid"));
        }
        // iss : The Issuer claim MUST be the client_id of the OAuth Client.
        final String iss = claims.getStringClaim(Claims.iss);
        if (iss == null || !client.getClientId().equals(iss)) {
            return Single.error(new InvalidRequestException("iss is missing or invalid"));
        }
        // exp : An expiration time that limits the validity lifetime of the signed authentication request.
        final Date exp = claims.getDateClaim(Claims.exp);
        if (exp == null) {
            return Single.error(new InvalidRequestException("exp is missing"));
        }
        DefaultJWTParser.evaluateExp(exp.getTime() / 1000, Instant.now(), 0);
        // iat : The time at which the signed authentication request was created.
        final Date iat = claims.getDateClaim(Claims.iat);
        if (iat == null) {
            return Single.error(new InvalidRequestException("iat is missing"));
        }
        // nbf : The time before which the signed authentication request is unacceptable.
        final Date nbf = claims.getDateClaim(Claims.nbf);
        if (nbf == null) {
            return Single.error(new InvalidRequestException("nbf is missing"));
        }
        DefaultJWTParser.evaluateNbf(nbf.getTime() / 1000, Instant.now(), 0);
        // jti : A unique identifier for the signed authentication request.
        if (claims.getStringClaim(Claims.jti) == null) {
            return Single.error(new InvalidRequestException("jti is missing"));
        }
    } catch (ParseException e) {
        return Single.error(new InvalidRequestException("Unable to read claims in the request parameter"));
    } catch (PrematureJWTException e) {
        return Single.error(new InvalidRequestException("nbf is invalid"));
    } catch (ExpiredJWTException e) {
        return Single.error(new InvalidRequestException("jwt has expired"));
    }
    return Single.just(jwt);
}
Also used : JWTClaimsSet(com.nimbusds.jwt.JWTClaimsSet) PrematureJWTException(io.gravitee.am.common.exception.jwt.PrematureJWTException) ExpiredJWTException(io.gravitee.am.common.exception.jwt.ExpiredJWTException) Collection(java.util.Collection) OpenIDProviderMetadata(io.gravitee.am.gateway.handler.oidc.service.discovery.OpenIDProviderMetadata) InvalidRequestException(io.gravitee.am.common.exception.oauth2.InvalidRequestException) ParseException(java.text.ParseException) Client(io.gravitee.am.model.oidc.Client) Date(java.util.Date)

Example 3 with PrematureJWTException

use of io.gravitee.am.common.exception.jwt.PrematureJWTException in project gravitee-access-management by gravitee-io.

the class DefaultJWTParser method evaluateNbf.

/**
 * Throw {@link ExpiredJWTException} if now is before nbf
 *
 * @param nbf
 * @param now
 */
public static void evaluateNbf(long nbf, Instant now, long clockSkew) {
    if (nbf > 0) {
        Instant nbfInstant = Instant.ofEpochSecond(nbf);
        if (now.isBefore(nbfInstant)) {
            long differenceMillis = nbfInstant.toEpochMilli() - now.toEpochMilli();
            String msg = "JWT must not be accepted before " + nbfInstant + ". Current time: " + now + ", a difference of " + differenceMillis + " milliseconds.  Allowed clock skew: " + clockSkew + " milliseconds.";
            throw new PrematureJWTException(msg);
        }
    }
}
Also used : Instant(java.time.Instant) PrematureJWTException(io.gravitee.am.common.exception.jwt.PrematureJWTException)

Aggregations

PrematureJWTException (io.gravitee.am.common.exception.jwt.PrematureJWTException)3 ExpiredJWTException (io.gravitee.am.common.exception.jwt.ExpiredJWTException)2 ParseException (java.text.ParseException)2 Instant (java.time.Instant)2 JOSEException (com.nimbusds.jose.JOSEException)1 JWTClaimsSet (com.nimbusds.jwt.JWTClaimsSet)1 SignedJWT (com.nimbusds.jwt.SignedJWT)1 MalformedJWTException (io.gravitee.am.common.exception.jwt.MalformedJWTException)1 SignatureException (io.gravitee.am.common.exception.jwt.SignatureException)1 InvalidRequestException (io.gravitee.am.common.exception.oauth2.InvalidRequestException)1 JWT (io.gravitee.am.common.jwt.JWT)1 OpenIDProviderMetadata (io.gravitee.am.gateway.handler.oidc.service.discovery.OpenIDProviderMetadata)1 Client (io.gravitee.am.model.oidc.Client)1 InvalidKeyException (java.security.InvalidKeyException)1 Collection (java.util.Collection)1 Date (java.util.Date)1 Map (java.util.Map)1