Search in sources :

Example 81 with JwtClaims

use of org.jose4j.jwt.JwtClaims in project light-rest-4j by networknt.

the class JwtVerifyHandler method handleRequest.

@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    HeaderMap headerMap = exchange.getRequestHeaders();
    String authorization = headerMap.getFirst(Headers.AUTHORIZATION);
    String jwt = JwtHelper.getJwtFromAuthorization(authorization);
    if (jwt != null) {
        try {
            JwtClaims claims = JwtHelper.verifyJwt(jwt);
            Map<String, Object> auditInfo = exchange.getAttachment(AuditHandler.AUDIT_INFO);
            // endpoint and swaggerOperation available. This handler will enrich the auditInfo.
            if (auditInfo == null) {
                auditInfo = new HashMap<>();
                exchange.putAttachment(AuditHandler.AUDIT_INFO, auditInfo);
            }
            auditInfo.put(Constants.CLIENT_ID_STRING, claims.getStringClaimValue(Constants.CLIENT_ID_STRING));
            auditInfo.put(Constants.USER_ID_STRING, claims.getStringClaimValue(Constants.USER_ID_STRING));
            auditInfo.put(Constants.SUBJECT_CLAIMS, claims);
            if (config != null && (Boolean) config.get(ENABLE_VERIFY_SCOPE) && SwaggerHelper.swagger != null) {
                Operation operation = null;
                SwaggerOperation swaggerOperation = (SwaggerOperation) auditInfo.get(Constants.SWAGGER_OPERATION_STRING);
                if (swaggerOperation == null) {
                    final NormalisedPath requestPath = new ApiNormalisedPath(exchange.getRequestURI());
                    final Optional<NormalisedPath> maybeApiPath = SwaggerHelper.findMatchingApiPath(requestPath);
                    if (!maybeApiPath.isPresent()) {
                        Status status = new Status(STATUS_INVALID_REQUEST_PATH);
                        exchange.setStatusCode(status.getStatusCode());
                        logger.error("Error in JwtVerifyHandler: " + status.toString());
                        exchange.getResponseSender().send(status.toString());
                        return;
                    }
                    final NormalisedPath swaggerPathString = maybeApiPath.get();
                    final Path swaggerPath = SwaggerHelper.swagger.getPath(swaggerPathString.original());
                    final HttpMethod httpMethod = HttpMethod.valueOf(exchange.getRequestMethod().toString());
                    operation = swaggerPath.getOperationMap().get(httpMethod);
                    if (operation == null) {
                        Status status = new Status(STATUS_METHOD_NOT_ALLOWED);
                        exchange.setStatusCode(status.getStatusCode());
                        logger.error("Error in JwtVerifyHandler: " + status.toString());
                        exchange.getResponseSender().send(status.toString());
                        return;
                    }
                    swaggerOperation = new SwaggerOperation(swaggerPathString, swaggerPath, httpMethod, operation);
                    auditInfo.put(Constants.SWAGGER_OPERATION_STRING, swaggerOperation);
                    auditInfo.put(Constants.ENDPOINT_STRING, swaggerPathString.normalised() + "@" + httpMethod);
                } else {
                    operation = swaggerOperation.getOperation();
                }
                // is there a scope token
                String scopeHeader = headerMap.getFirst(Constants.SCOPE_TOKEN);
                String scopeJwt = JwtHelper.getJwtFromAuthorization(scopeHeader);
                List<String> secondaryScopes = null;
                if (scopeJwt != null) {
                    try {
                        JwtClaims scopeClaims = JwtHelper.verifyJwt(scopeJwt);
                        secondaryScopes = scopeClaims.getStringListClaimValue("scope");
                        auditInfo.put(Constants.SCOPE_CLIENT_ID_STRING, scopeClaims.getStringClaimValue(Constants.CLIENT_ID_STRING));
                        auditInfo.put(Constants.ACCESS_CLAIMS, scopeClaims);
                    } catch (InvalidJwtException | MalformedClaimException e) {
                        logger.error("InvalidJwtException", e);
                        Status status = new Status(STATUS_INVALID_SCOPE_TOKEN);
                        exchange.setStatusCode(status.getStatusCode());
                        logger.error("Error in JwtVerifyHandler: " + status.toString());
                        exchange.getResponseSender().send(status.toString());
                        return;
                    } catch (ExpiredTokenException e) {
                        Status status = new Status(STATUS_SCOPE_TOKEN_EXPIRED);
                        exchange.setStatusCode(status.getStatusCode());
                        logger.error("Error in JwtVerifyHandler: " + status.toString());
                        exchange.getResponseSender().send(status.toString());
                        return;
                    }
                }
                // get scope defined in swagger spec for this endpoint.
                List<String> specScopes = null;
                List<Map<String, List<String>>> security = operation.getSecurity();
                if (security != null) {
                    for (Map<String, List<String>> requirement : security) {
                        specScopes = requirement.get(SwaggerHelper.oauth2Name);
                        if (specScopes != null)
                            break;
                    }
                }
                // validate scope
                if (scopeHeader != null) {
                    if (secondaryScopes == null || !matchedScopes(secondaryScopes, specScopes)) {
                        Status status = new Status(STATUS_SCOPE_TOKEN_SCOPE_MISMATCH, secondaryScopes, specScopes);
                        exchange.setStatusCode(status.getStatusCode());
                        logger.error("Error in JwtVerifyHandler: " + status.toString());
                        exchange.getResponseSender().send(status.toString());
                        return;
                    }
                } else {
                    // no scope token, verify scope from auth token.
                    List<String> primaryScopes;
                    try {
                        primaryScopes = claims.getStringListClaimValue("scope");
                    } catch (MalformedClaimException e) {
                        logger.error("MalformedClaimException", e);
                        Status status = new Status(STATUS_INVALID_AUTH_TOKEN);
                        exchange.setStatusCode(status.getStatusCode());
                        logger.error("Error in JwtVerifyHandler: " + status.toString());
                        exchange.getResponseSender().send(status.toString());
                        return;
                    }
                    if (!matchedScopes(primaryScopes, specScopes)) {
                        Status status = new Status(STATUS_AUTH_TOKEN_SCOPE_MISMATCH, primaryScopes, specScopes);
                        exchange.setStatusCode(status.getStatusCode());
                        logger.error("Error in JwtVerifyHandler: " + status.toString());
                        exchange.getResponseSender().send(status.toString());
                        return;
                    }
                }
            }
            next.handleRequest(exchange);
        } catch (InvalidJwtException e) {
            // only log it and unauthorized is returned.
            logger.error("Exception: ", e);
            Status status = new Status(STATUS_INVALID_AUTH_TOKEN);
            exchange.setStatusCode(status.getStatusCode());
            logger.error("Error in JwtVerifyHandler: " + status.toString());
            exchange.getResponseSender().send(status.toString());
        } catch (ExpiredTokenException e) {
            Status status = new Status(STATUS_AUTH_TOKEN_EXPIRED);
            exchange.setStatusCode(status.getStatusCode());
            logger.error("Error in JwtVerifyHandler: " + status.toString());
            exchange.getResponseSender().send(status.toString());
        }
    } else {
        Status status = new Status(STATUS_MISSING_AUTH_TOKEN);
        exchange.setStatusCode(status.getStatusCode());
        logger.error("Error in JwtVerifyHandler: " + status.toString());
        exchange.getResponseSender().send(status.toString());
    }
}
Also used : Status(com.networknt.status.Status) InvalidJwtException(org.jose4j.jwt.consumer.InvalidJwtException) ExpiredTokenException(com.networknt.exception.ExpiredTokenException) JwtClaims(org.jose4j.jwt.JwtClaims) HttpString(io.undertow.util.HttpString) MalformedClaimException(org.jose4j.jwt.MalformedClaimException) HeaderMap(io.undertow.util.HeaderMap) List(java.util.List) HashMap(java.util.HashMap) HeaderMap(io.undertow.util.HeaderMap) Map(java.util.Map)

Example 82 with JwtClaims

use of org.jose4j.jwt.JwtClaims in project wildfly-swarm by wildfly-swarm.

the class JWTCredential method getName.

/**
 * This just parses the token without validation to extract one of the following in order to obtain
 * the name to be used for the principal:
 * upn
 * preferred_username
 * subject
 *
 * If there is an exception it sets the name to INVALID_TOKEN_NAME and saves the exception for access
 * via {@link #getJwtException()}
 *
 * @return the name to use for the principal
 */
public String getName() {
    if (name == null) {
        name = "INVALID_TOKEN_NAME";
        try {
            // Build a JwtConsumer that doesn't check signatures or do any validation.
            JwtConsumer firstPassJwtConsumer = new JwtConsumerBuilder().setSkipAllValidators().setDisableRequireSignature().setSkipSignatureVerification().build();
            // The first JwtConsumer is basically just used to parse the JWT into a JwtContext object.
            JwtContext jwtContext = firstPassJwtConsumer.process(bearerToken);
            JwtClaims claimsSet = jwtContext.getJwtClaims();
            // We have to determine the unique name to use as the principal name. It comes from upn, preferred_username, sub in that order
            name = claimsSet.getClaimValue("upn", String.class);
            if (name == null) {
                name = claimsSet.getClaimValue("preferred_username", String.class);
                if (name == null) {
                    name = claimsSet.getSubject();
                }
            }
        } catch (Exception e) {
            jwtException = e;
        }
    }
    return name;
}
Also used : JwtClaims(org.jose4j.jwt.JwtClaims) JwtConsumerBuilder(org.jose4j.jwt.consumer.JwtConsumerBuilder) JwtConsumer(org.jose4j.jwt.consumer.JwtConsumer) JwtContext(org.jose4j.jwt.consumer.JwtContext)

Example 83 with JwtClaims

use of org.jose4j.jwt.JwtClaims in project wildfly-swarm by wildfly-swarm.

the class TokenUtils method createToken.

public static String createToken(String groupName) throws Exception {
    JwtClaims claims = new JwtClaims();
    claims.setIssuer("http://testsuite-jwt-issuer.io");
    claims.setSubject(SUBJECT);
    claims.setStringListClaim("groups", groupName);
    claims.setClaim("upn", "jdoe@example.com");
    claims.setExpirationTimeMinutesInTheFuture(1);
    JsonWebSignature jws = new JsonWebSignature();
    jws.setPayload(claims.toJson());
    jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
    jws.setKey(getPrivateKey());
    return jws.getCompactSerialization();
}
Also used : JsonWebSignature(org.jose4j.jws.JsonWebSignature) JwtClaims(org.jose4j.jwt.JwtClaims)

Example 84 with JwtClaims

use of org.jose4j.jwt.JwtClaims in project light-rest-4j by networknt.

the class JwtVerifyHandler method handleRequest.

@Override
public void handleRequest(final HttpServerExchange exchange) throws Exception {
    HeaderMap headerMap = exchange.getRequestHeaders();
    String authorization = headerMap.getFirst(Headers.AUTHORIZATION);
    String jwt = jwtVerifier.getJwtFromAuthorization(authorization);
    boolean ignoreExpiry = config.get(IGNORE_JWT_EXPIRY) == null ? false : (boolean) config.get(IGNORE_JWT_EXPIRY);
    if (jwt != null) {
        try {
            JwtClaims claims = jwtVerifier.verifyJwt(jwt, ignoreExpiry, true);
            Map<String, Object> auditInfo = exchange.getAttachment(AttachmentConstants.AUDIT_INFO);
            // endpoint and swaggerOperation available. This handler will enrich the auditInfo.
            if (auditInfo == null) {
                auditInfo = new HashMap<>();
                exchange.putAttachment(AttachmentConstants.AUDIT_INFO, auditInfo);
            }
            String clientId = claims.getStringClaimValue(Constants.CLIENT_ID_STRING);
            // try to get the cid as some OAuth tokens name it as cid like Okta.
            if (clientId == null)
                clientId = claims.getStringClaimValue(Constants.CID_STRING);
            auditInfo.put(Constants.CLIENT_ID_STRING, clientId);
            String userId = claims.getStringClaimValue(Constants.USER_ID_STRING);
            // try to get the uid as some OAuth tokens name it as uid like Okta.
            if (userId == null)
                userId = claims.getStringClaimValue(Constants.UID_STRING);
            auditInfo.put(Constants.USER_ID_STRING, userId);
            auditInfo.put(Constants.SUBJECT_CLAIMS, claims);
            String callerId = headerMap.getFirst(HttpStringConstants.CALLER_ID);
            if (callerId != null)
                auditInfo.put(Constants.CALLER_ID_STRING, callerId);
            if (config != null && (Boolean) config.get(ENABLE_VERIFY_JWT_SCOPE_TOKEN) && OpenApiHelper.openApi3 != null) {
                Operation operation = null;
                OpenApiOperation openApiOperation = (OpenApiOperation) auditInfo.get(Constants.OPENAPI_OPERATION_STRING);
                if (openApiOperation == null) {
                    final NormalisedPath requestPath = new ApiNormalisedPath(exchange.getRequestURI(), basePath);
                    final Optional<NormalisedPath> maybeApiPath = OpenApiHelper.getInstance().findMatchingApiPath(requestPath);
                    if (!maybeApiPath.isPresent()) {
                        setExchangeStatus(exchange, STATUS_INVALID_REQUEST_PATH);
                        return;
                    }
                    final NormalisedPath swaggerPathString = maybeApiPath.get();
                    final Path swaggerPath = OpenApiHelper.openApi3.getPath(swaggerPathString.original());
                    final String httpMethod = exchange.getRequestMethod().toString().toLowerCase();
                    operation = swaggerPath.getOperation(httpMethod);
                    if (operation == null) {
                        setExchangeStatus(exchange, STATUS_METHOD_NOT_ALLOWED, httpMethod, swaggerPathString.normalised());
                        return;
                    }
                    openApiOperation = new OpenApiOperation(swaggerPathString, swaggerPath, httpMethod, operation);
                    auditInfo.put(Constants.OPENAPI_OPERATION_STRING, openApiOperation);
                    auditInfo.put(Constants.ENDPOINT_STRING, swaggerPathString.normalised() + "@" + httpMethod);
                } else {
                    operation = openApiOperation.getOperation();
                }
                // is there a scope token
                String scopeHeader = headerMap.getFirst(HttpStringConstants.SCOPE_TOKEN);
                String scopeJwt = jwtVerifier.getJwtFromAuthorization(scopeHeader);
                List<String> secondaryScopes = null;
                if (scopeJwt != null) {
                    try {
                        JwtClaims scopeClaims = jwtVerifier.verifyJwt(scopeJwt, ignoreExpiry, true);
                        Object scopeClaim = scopeClaims.getClaimValue(Constants.SCOPE_STRING);
                        if (scopeClaim instanceof String) {
                            secondaryScopes = Arrays.asList(scopeClaims.getStringClaimValue(Constants.SCOPE_STRING).split(" "));
                        } else if (scopeClaim instanceof List) {
                            secondaryScopes = scopeClaims.getStringListClaimValue(Constants.SCOPE_STRING);
                        }
                        if (secondaryScopes == null || secondaryScopes.isEmpty()) {
                            // some IDPs like Okta and Microsoft call scope claim "scp" instead of "scope"
                            Object scpClaim = scopeClaims.getClaimValue(Constants.SCP_STRING);
                            if (scpClaim instanceof String) {
                                secondaryScopes = Arrays.asList(scopeClaims.getStringClaimValue(Constants.SCP_STRING).split(" "));
                            } else if (scpClaim instanceof List) {
                                secondaryScopes = scopeClaims.getStringListClaimValue(Constants.SCP_STRING);
                            }
                        }
                        auditInfo.put(Constants.SCOPE_CLIENT_ID_STRING, scopeClaims.getStringClaimValue(Constants.CLIENT_ID_STRING));
                        auditInfo.put(Constants.ACCESS_CLAIMS, scopeClaims);
                    } catch (InvalidJwtException | MalformedClaimException e) {
                        logger.error("InvalidJwtException", e);
                        setExchangeStatus(exchange, STATUS_INVALID_SCOPE_TOKEN);
                        return;
                    } catch (ExpiredTokenException e) {
                        logger.error("ExpiredTokenException", e);
                        setExchangeStatus(exchange, STATUS_SCOPE_TOKEN_EXPIRED);
                        return;
                    }
                }
                // validate the scope against the scopes configured in the OpenAPI spec
                if ((Boolean) config.get(ENABLE_VERIFY_SCOPE)) {
                    // get scope defined in OpenAPI spec for this endpoint.
                    Collection<String> specScopes = null;
                    Collection<SecurityRequirement> securityRequirements = operation.getSecurityRequirements();
                    if (securityRequirements != null) {
                        for (SecurityRequirement requirement : securityRequirements) {
                            SecurityParameter securityParameter = null;
                            for (String oauth2Name : OpenApiHelper.oauth2Names) {
                                securityParameter = requirement.getRequirement(oauth2Name);
                                if (securityParameter != null)
                                    break;
                            }
                            if (securityParameter != null)
                                specScopes = securityParameter.getParameters();
                            if (specScopes != null)
                                break;
                        }
                    }
                    // validate scope
                    if (scopeHeader != null) {
                        if (secondaryScopes == null || !matchedScopes(secondaryScopes, specScopes)) {
                            setExchangeStatus(exchange, STATUS_SCOPE_TOKEN_SCOPE_MISMATCH, secondaryScopes, specScopes);
                            return;
                        }
                    } else {
                        // no scope token, verify scope from auth token.
                        List<String> primaryScopes = null;
                        try {
                            Object scopeClaim = claims.getClaimValue(Constants.SCOPE_STRING);
                            if (scopeClaim instanceof String) {
                                primaryScopes = Arrays.asList(claims.getStringClaimValue(Constants.SCOPE_STRING).split(" "));
                            } else if (scopeClaim instanceof List) {
                                primaryScopes = claims.getStringListClaimValue(Constants.SCOPE_STRING);
                            }
                            if (primaryScopes == null || primaryScopes.isEmpty()) {
                                // some IDPs like Okta and Microsoft call scope claim "scp" instead of "scope"
                                Object scpClaim = claims.getClaimValue(Constants.SCP_STRING);
                                if (scpClaim instanceof String) {
                                    primaryScopes = Arrays.asList(claims.getStringClaimValue(Constants.SCP_STRING).split(" "));
                                } else if (scpClaim instanceof List) {
                                    primaryScopes = claims.getStringListClaimValue(Constants.SCP_STRING);
                                }
                            }
                        } catch (MalformedClaimException e) {
                            logger.error("MalformedClaimException", e);
                            setExchangeStatus(exchange, STATUS_INVALID_AUTH_TOKEN);
                            return;
                        }
                        if (!matchedScopes(primaryScopes, specScopes)) {
                            setExchangeStatus(exchange, STATUS_AUTH_TOKEN_SCOPE_MISMATCH, primaryScopes, specScopes);
                            return;
                        }
                    }
                }
            // end scope validation
            }
            Handler.next(exchange, next);
        } catch (InvalidJwtException e) {
            // only log it and unauthorized is returned.
            logger.error("InvalidJwtException: ", e);
            setExchangeStatus(exchange, STATUS_INVALID_AUTH_TOKEN);
        } catch (ExpiredTokenException e) {
            logger.error("ExpiredTokenException", e);
            setExchangeStatus(exchange, STATUS_AUTH_TOKEN_EXPIRED);
        }
    } else {
        setExchangeStatus(exchange, STATUS_MISSING_AUTH_TOKEN);
    }
}
Also used : Path(com.networknt.oas.model.Path) InvalidJwtException(org.jose4j.jwt.consumer.InvalidJwtException) ExpiredTokenException(com.networknt.exception.ExpiredTokenException) JwtClaims(org.jose4j.jwt.JwtClaims) Operation(com.networknt.oas.model.Operation) MalformedClaimException(org.jose4j.jwt.MalformedClaimException) HeaderMap(io.undertow.util.HeaderMap) SecurityParameter(com.networknt.oas.model.SecurityParameter) SecurityRequirement(com.networknt.oas.model.SecurityRequirement)

Example 85 with JwtClaims

use of org.jose4j.jwt.JwtClaims in project light-4j by networknt.

the class Http2ClientPoolTest method getJwt.

private static String getJwt(int expiredInSeconds) throws Exception {
    JwtClaims claims = getTestClaims();
    claims.setExpirationTime(NumericDate.fromMilliseconds(System.currentTimeMillis() + expiredInSeconds * 1000));
    return getJwt(claims);
}
Also used : JwtClaims(org.jose4j.jwt.JwtClaims)

Aggregations

JwtClaims (org.jose4j.jwt.JwtClaims)130 Test (org.junit.Test)47 JwtConsumer (org.jose4j.jwt.consumer.JwtConsumer)23 JwtConsumerBuilder (org.jose4j.jwt.consumer.JwtConsumerBuilder)23 InvalidJwtException (org.jose4j.jwt.consumer.InvalidJwtException)21 MalformedClaimException (org.jose4j.jwt.MalformedClaimException)19 JoseException (org.jose4j.lang.JoseException)17 lombok.val (lombok.val)15 JsonWebSignature (org.jose4j.jws.JsonWebSignature)15 Map (java.util.Map)14 JwtContext (org.jose4j.jwt.consumer.JwtContext)11 NumericDate (org.jose4j.jwt.NumericDate)9 JsonWebStructure (org.jose4j.jwx.JsonWebStructure)9 HashMap (java.util.HashMap)7 KeyStoreException (java.security.KeyStoreException)6 ArrayList (java.util.ArrayList)5 OidcRegisteredService (org.apereo.cas.services.OidcRegisteredService)5 ExpiredTokenException (com.networknt.exception.ExpiredTokenException)4 JwksVerificationKeyResolver (org.jose4j.keys.resolvers.JwksVerificationKeyResolver)4 Test (org.junit.jupiter.api.Test)4