Search in sources :

Example 21 with Claim

use of com.auth0.android.jwt.Claim in project auth0-java by auth0.

the class IdTokenVerifier method verify.

/**
 * Verifies a provided ID Token follows the <a href="https://openid.net/specs/openid-connect-core-1_0-final.html#IDTokenValidation">OIDC specification.</a>
 *
 * @param token                the ID Token to verify. Must not be null or empty.
 * @param nonce                the nonce expected on the ID token, which must match the nonce specified on the authorization request.
 *                             If null, no validation of the nonce will occur.
 * @param maxAuthenticationAge The maximum authentication age allowed, which specifies the allowable elapsed time in seconds
 *                             since the last time the end-user was actively authenticated. This must match the specified
 *                             {@code max_age} parameter specified on the authorization request. If null, no validation
 *                             of the {@code auth_time} claim will occur.
 * @throws IdTokenValidationException if:
 *                                    <ul>
 *                                        <li>The ID token is null</li>
 *                                        <li>The ID token's signing algorithm is not supported</li>
 *                                        <li>The ID token's signature is invalid</li>
 *                                        <li>Any of the ID token's claims are invalid</li>
 *                                    </ul>
 * @see IdTokenVerifier#verify(String)
 * @see IdTokenVerifier#verify(String, String)
 */
public void verify(String token, String nonce, Integer maxAuthenticationAge) throws IdTokenValidationException {
    if (isEmpty(token)) {
        throw new IdTokenValidationException("ID token is required but missing");
    }
    DecodedJWT decoded = this.signatureVerifier.verifySignature(token);
    if (isEmpty(decoded.getIssuer())) {
        throw new IdTokenValidationException("Issuer (iss) claim must be a string present in the ID token");
    }
    if (!decoded.getIssuer().equals(this.issuer)) {
        throw new IdTokenValidationException(String.format("Issuer (iss) claim mismatch in the ID token, expected \"%s\", found \"%s\"", this.issuer, decoded.getIssuer()));
    }
    if (isEmpty(decoded.getSubject())) {
        throw new IdTokenValidationException("Subject (sub) claim must be a string present in the ID token");
    }
    final List<String> audience = decoded.getAudience();
    if (audience == null) {
        throw new IdTokenValidationException("Audience (aud) claim must be a string or array of strings present in the ID token");
    }
    if (!audience.contains(this.audience)) {
        throw new IdTokenValidationException(String.format("Audience (aud) claim mismatch in the ID token; expected \"%s\" but found \"%s\"", this.audience, decoded.getAudience()));
    }
    // Org verification
    if (this.organization != null) {
        String orgClaim = decoded.getClaim("org_id").asString();
        if (isEmpty(orgClaim)) {
            throw new IdTokenValidationException("Organization Id (org_id) claim must be a string present in the ID token");
        }
        if (!this.organization.equals(orgClaim)) {
            throw new IdTokenValidationException(String.format("Organization (org_id) claim mismatch in the ID token; expected \"%s\" but found \"%s\"", this.organization, orgClaim));
        }
    }
    final Calendar cal = Calendar.getInstance();
    final Date now = this.clock != null ? this.clock : cal.getTime();
    final int clockSkew = this.leeway != null ? this.leeway : DEFAULT_LEEWAY;
    if (decoded.getExpiresAt() == null) {
        throw new IdTokenValidationException("Expiration Time (exp) claim must be a number present in the ID token");
    }
    cal.setTime(decoded.getExpiresAt());
    cal.add(Calendar.SECOND, clockSkew);
    Date expDate = cal.getTime();
    if (now.after(expDate)) {
        throw new IdTokenValidationException(String.format("Expiration Time (exp) claim error in the ID token; current time (%d) is after expiration time (%d)", now.getTime() / 1000, expDate.getTime() / 1000));
    }
    if (decoded.getIssuedAt() == null) {
        throw new IdTokenValidationException("Issued At (iat) claim must be a number present in the ID token");
    }
    cal.setTime(decoded.getIssuedAt());
    cal.add(Calendar.SECOND, -1 * clockSkew);
    if (nonce != null) {
        String nonceClaim = decoded.getClaim(NONCE_CLAIM).asString();
        if (isEmpty(nonceClaim)) {
            throw new IdTokenValidationException("Nonce (nonce) claim must be a string present in the ID token");
        }
        if (!nonce.equals(nonceClaim)) {
            throw new IdTokenValidationException(String.format("Nonce (nonce) claim mismatch in the ID token; expected \"%s\", found \"%s\"", nonce, nonceClaim));
        }
    }
    if (audience.size() > 1) {
        String azpClaim = decoded.getClaim(AZP_CLAIM).asString();
        if (isEmpty(azpClaim)) {
            throw new IdTokenValidationException("Authorized Party (azp) claim must be a string present in the ID token when Audience (aud) claim has multiple values");
        }
        if (!this.audience.equals(azpClaim)) {
            throw new IdTokenValidationException(String.format("Authorized Party (azp) claim mismatch in the ID token; expected \"%s\", found \"%s\"", this.audience, azpClaim));
        }
    }
    if (maxAuthenticationAge != null) {
        Date authTime = decoded.getClaim(AUTH_TIME_CLAIM).asDate();
        if (authTime == null) {
            throw new IdTokenValidationException("Authentication Time (auth_time) claim must be a number present in the ID token when Max Age (max_age) is specified");
        }
        cal.setTime(authTime);
        cal.add(Calendar.SECOND, maxAuthenticationAge);
        cal.add(Calendar.SECOND, clockSkew);
        Date authTimeDate = cal.getTime();
        if (now.after(authTimeDate)) {
            throw new IdTokenValidationException(String.format("Authentication Time (auth_time) claim in the ID token indicates that too much time has passed since the last end-user authentication. Current time (%d) is after last auth at (%d)", now.getTime() / 1000, authTimeDate.getTime() / 1000));
        }
    }
}
Also used : IdTokenValidationException(com.auth0.exception.IdTokenValidationException) Calendar(java.util.Calendar) DecodedJWT(com.auth0.jwt.interfaces.DecodedJWT) Date(java.util.Date)

Example 22 with Claim

use of com.auth0.android.jwt.Claim in project restheart by SoftInstigate.

the class JwtAuthenticationMechanism method authenticate.

@Override
public AuthenticationMechanism.AuthenticationMechanismOutcome authenticate(HttpServerExchange hse, SecurityContext sc) {
    try {
        String token = getToken(hse);
        if (token != null) {
            if (base64Encoded) {
                token = StringUtils.newStringUtf8(Base64.getUrlDecoder().decode(token));
            }
            DecodedJWT verifiedJwt = jwtVerifier.verify(token);
            String subject = verifiedJwt.getClaim(usernameClaim).asString();
            if (subject == null) {
                LOGGER.debug("username not specified with claim {}", usernameClaim);
                sc.authenticationFailed("JwtAuthenticationManager", "username not specified");
                return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
            }
            Set<String> actualRoles = new LinkedHashSet<>();
            if (rolesClaim != null) {
                Claim _roles = verifiedJwt.getClaim(rolesClaim);
                if (_roles != null && !_roles.isNull()) {
                    try {
                        String[] __roles = _roles.asArray(String.class);
                        if (__roles != null) {
                            for (String role : __roles) {
                                actualRoles.add(role);
                            }
                        } else {
                            LOGGER.debug("roles is not an array: {}", _roles.asString());
                            return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
                        }
                    } catch (JWTDecodeException ex) {
                        LOGGER.warn("Jwt cannot get roles from claim {}, " + "extepected an array of strings: {}", rolesClaim, _roles.toString());
                    }
                }
            } else if (this.fixedRoles != null) {
                actualRoles.addAll(this.fixedRoles);
            }
            if (this.extraJwtVerifier != null) {
                this.extraJwtVerifier.accept(verifiedJwt);
            }
            var jwtPayload = new String(Base64.getUrlDecoder().decode(verifiedJwt.getPayload()), Charset.forName("UTF-8"));
            JwtAccount account = new JwtAccount(subject, actualRoles, jwtPayload);
            sc.authenticationComplete(account, "JwtAuthenticationManager", false);
            Request.of(hse).addXForwardedHeader("Jwt-Payload", jwtPayload);
            return AuthenticationMechanismOutcome.AUTHENTICATED;
        }
    } catch (JWTVerificationException ex) {
        LOGGER.debug("Jwt not verified: {}", ex.getMessage());
        return AuthenticationMechanismOutcome.NOT_AUTHENTICATED;
    }
    return AuthenticationMechanismOutcome.NOT_ATTEMPTED;
}
Also used : LinkedHashSet(java.util.LinkedHashSet) JWTVerificationException(com.auth0.jwt.exceptions.JWTVerificationException) JWTDecodeException(com.auth0.jwt.exceptions.JWTDecodeException) JwtAccount(org.restheart.security.JwtAccount) DecodedJWT(com.auth0.jwt.interfaces.DecodedJWT) Claim(com.auth0.jwt.interfaces.Claim)

Example 23 with Claim

use of com.auth0.android.jwt.Claim in project ARLAS-server by gisaia.

the class AuthorizationFilter method filter.

@Override
public void filter(ContainerRequestContext ctx) {
    Transaction transaction = ElasticApm.currentTransaction();
    boolean isPublic = ctx.getUriInfo().getPath().concat(":").concat(ctx.getMethod()).matches(authConf.getPublicRegex());
    String header = ctx.getHeaderString(HttpHeaders.AUTHORIZATION);
    if (header == null || (header != null && !header.toLowerCase().startsWith("bearer "))) {
        if (isPublic || ctx.getMethod() == "OPTIONS") {
            return;
        } else {
            ctx.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
        }
    }
    try {
        // header presence and format already checked before in AuthenticationFilter
        DecodedJWT jwt = jwtVerifier.verify(header.substring(7));
        // remove it in case it's been set manually
        ctx.getHeaders().remove(authConf.headerUser);
        String userId = jwt.getSubject();
        if (!StringUtil.isNullOrEmpty(userId)) {
            ctx.getHeaders().putSingle(authConf.headerUser, userId);
            transaction.setUser(userId, "", "");
        }
        // remove it in case it's been set manually
        ctx.getHeaders().remove(authConf.headerGroup);
        Claim jwtClaimRoles = jwt.getClaim(authConf.claimRoles);
        if (!jwtClaimRoles.isNull()) {
            List<String> groups = jwtClaimRoles.asList(String.class).stream().filter(r -> r.toLowerCase().startsWith("group")).collect(Collectors.toList());
            ctx.setProperty("groups", groups);
            ctx.getHeaders().put(authConf.headerGroup, groups);
        }
        Claim jwtClaimPermissions = jwt.getClaim(authConf.claimPermissions);
        if (!jwtClaimPermissions.isNull()) {
            ArlasClaims arlasClaims = new ArlasClaims(jwtClaimPermissions.asList(String.class));
            ctx.setProperty("claims", arlasClaims);
            if (arlasClaims.isAllowed(ctx.getMethod(), ctx.getUriInfo().getPath())) {
                arlasClaims.injectHeaders(ctx.getHeaders(), transaction);
                return;
            }
        }
        if (isPublic) {
            return;
        } else {
            ctx.abortWith(Response.status(Response.Status.FORBIDDEN).build());
        }
    } catch (JWTVerificationException e) {
        LOGGER.warn("JWT verification failed.", e);
        if (!isPublic) {
            ctx.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
        }
        return;
    }
    ctx.abortWith(Response.status(Response.Status.FORBIDDEN).build());
}
Also used : X509Certificate(java.security.cert.X509Certificate) JWT(com.auth0.jwt.JWT) Transaction(co.elastic.apm.api.Transaction) StringUtil(io.arlas.server.core.utils.StringUtil) Provider(javax.ws.rs.ext.Provider) CertificateFactory(java.security.cert.CertificateFactory) DecodedJWT(com.auth0.jwt.interfaces.DecodedJWT) URL(java.net.URL) LoggerFactory(org.slf4j.LoggerFactory) Priorities(javax.ws.rs.Priorities) ContainerRequestFilter(javax.ws.rs.container.ContainerRequestFilter) ContainerRequestContext(javax.ws.rs.container.ContainerRequestContext) Algorithm(com.auth0.jwt.algorithms.Algorithm) RSAPublicKey(java.security.interfaces.RSAPublicKey) JWTVerifier(com.auth0.jwt.interfaces.JWTVerifier) Claim(com.auth0.jwt.interfaces.Claim) JWTVerificationException(com.auth0.jwt.exceptions.JWTVerificationException) ArlasAuthConfiguration(io.arlas.server.core.app.ArlasAuthConfiguration) Logger(org.slf4j.Logger) ElasticApm(co.elastic.apm.api.ElasticApm) FileInputStream(java.io.FileInputStream) Collectors(java.util.stream.Collectors) Priority(javax.annotation.Priority) List(java.util.List) HttpHeaders(javax.ws.rs.core.HttpHeaders) Response(javax.ws.rs.core.Response) InputStream(java.io.InputStream) JWTVerificationException(com.auth0.jwt.exceptions.JWTVerificationException) Transaction(co.elastic.apm.api.Transaction) DecodedJWT(com.auth0.jwt.interfaces.DecodedJWT) Claim(com.auth0.jwt.interfaces.Claim)

Example 24 with Claim

use of com.auth0.android.jwt.Claim in project drug-formulary-ri by HL7-DaVinci.

the class PatientAuthorizationInterceptor method verify.

/**
 * Helper method to verify and decode the access token
 *
 * @param token       - the access token
 * @param fhirBaseUrl - the base url of this FHIR server
 * @return the base interface Patient ID datatype if the jwt token is verified
 *         and contains a patient ID in it claim, otherwise null.
 * @throws SignatureVerificationException
 * @throws TokenExpiredException
 * @throws JWTVerificationException
 */
private IIdType verify(String token, String fhirBaseUrl) throws SignatureVerificationException, TokenExpiredException, JWTVerificationException {
    Algorithm algorithm = Algorithm.RSA256(OauthEndpointController.getPublicKey(), null);
    logger.fine("Verifying JWT token iss and aud is " + fhirBaseUrl);
    JWTVerifier verifier = JWT.require(algorithm).withIssuer(fhirBaseUrl).withAudience(fhirBaseUrl).build();
    DecodedJWT jwt = verifier.verify(token);
    String patientId = jwt.getClaim("patient_id").asString();
    if (patientId != null)
        return new IdType("Patient", patientId);
    return null;
}
Also used : Algorithm(com.auth0.jwt.algorithms.Algorithm) JWTVerifier(com.auth0.jwt.JWTVerifier) DecodedJWT(com.auth0.jwt.interfaces.DecodedJWT) IIdType(org.hl7.fhir.instance.model.api.IIdType) IdType(org.hl7.fhir.r4.model.IdType)

Example 25 with Claim

use of com.auth0.android.jwt.Claim in project drug-formulary-ri by HL7-DaVinci.

the class AuthUtils method authCodeIsValid.

/**
 * Verify the authorization code provided in the POST request's claim to /token
 * path
 *
 * @param code        - the authorization code provided in the request
 * @param baseUrl     - this server base URL
 * @param redirectURI - the requestor/client redirect URI provided in the POST
 *                    request
 * @param clientId    - the client ID retrieved from the request's Authorization
 *                    Header
 * @return patientId if the authorization code is valid, otherwise null
 */
public static String authCodeIsValid(String code, String baseUrl, String redirectURI, String clientId) {
    String patientId = null;
    try {
        Algorithm algorithm = Algorithm.RSA256(OauthEndpointController.getPublicKey(), null);
        JWTVerifier verifier = JWT.require(algorithm).withIssuer(baseUrl).withAudience(baseUrl).withClaim(REDIRECT_URI_KEY, redirectURI).withClaim(CLIENT_ID_KEY, clientId).build();
        DecodedJWT jwt = verifier.verify(code);
        String username = jwt.getClaim("username").asString();
        User user = User.getUser(username);
        patientId = user != null ? user.getPatientId() : null;
    } catch (SignatureVerificationException | InvalidClaimException e) {
        logger.log(Level.SEVERE, "TokenEndpoint::Authorization code is invalid: Signature invalid or claim value invalid", e);
    } catch (AlgorithmMismatchException e) {
        logger.log(Level.SEVERE, "TokenEndpoint::Authorization code is invalid: Algorithm mismatch", e);
    } catch (TokenExpiredException e) {
        logger.log(Level.SEVERE, "TokenEndpoint::Authorization code is invalid: Token expired", e);
    } catch (JWTVerificationException e) {
        logger.log(Level.SEVERE, "TokenEndpoint::Authorization code is invalid: Please obtain a new code", e);
    }
    return patientId;
}
Also used : JWTVerificationException(com.auth0.jwt.exceptions.JWTVerificationException) TokenExpiredException(com.auth0.jwt.exceptions.TokenExpiredException) SignatureVerificationException(com.auth0.jwt.exceptions.SignatureVerificationException) InvalidClaimException(com.auth0.jwt.exceptions.InvalidClaimException) Algorithm(com.auth0.jwt.algorithms.Algorithm) JWTVerifier(com.auth0.jwt.JWTVerifier) DecodedJWT(com.auth0.jwt.interfaces.DecodedJWT) AlgorithmMismatchException(com.auth0.jwt.exceptions.AlgorithmMismatchException)

Aggregations

Claim (com.auth0.jwt.interfaces.Claim)110 Test (org.junit.Test)67 DecodedJWT (com.auth0.jwt.interfaces.DecodedJWT)62 JsonNode (com.fasterxml.jackson.databind.JsonNode)42 Algorithm (com.auth0.jwt.algorithms.Algorithm)24 Date (java.util.Date)24 JWTVerificationException (com.auth0.jwt.exceptions.JWTVerificationException)21 RSAPublicKey (java.security.interfaces.RSAPublicKey)21 Test (org.junit.jupiter.api.Test)18 RSAPrivateKey (java.security.interfaces.RSAPrivateKey)17 JWTVerifier (com.auth0.jwt.JWTVerifier)15 JwksTestKeySource (org.sdase.commons.server.auth.service.testsources.JwksTestKeySource)14 JsonObject (com.google.gson.JsonObject)10 HashMap (java.util.HashMap)9 UserPojo (com.auth0.jwt.UserPojo)8 IOException (java.io.IOException)8 Map (java.util.Map)8 TestingProcessManager (io.supertokens.test.TestingProcessManager)7 NullClaim (com.auth0.jwt.impl.NullClaim)5 JWT (com.auth0.jwt.JWT)4