Search in sources :

Example 1 with SecurityRequirement

use of com.networknt.oas.model.SecurityRequirement 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));
            if (config != null && (Boolean) config.get(ENABLE_VERIFY_SCOPE) && 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());
                    final Optional<NormalisedPath> maybeApiPath = OpenApiHelper.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 = OpenApiHelper.openApi3.getPath(swaggerPathString.original());
                    final String httpMethod = exchange.getRequestMethod().toString().toLowerCase();
                    operation = swaggerPath.getOperation(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;
                    }
                    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(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));
                    } 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.
                Collection<String> specScopes = null;
                Collection<SecurityRequirement> securityRequirements = operation.getSecurityRequirements();
                if (securityRequirements != null) {
                    for (SecurityRequirement requirement : securityRequirements) {
                        SecurityParameter securityParameter = requirement.getRequirement(OpenApiHelper.oauth2Name);
                        specScopes = securityParameter.getParameters();
                        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) 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)

Aggregations

ExpiredTokenException (com.networknt.exception.ExpiredTokenException)1 Operation (com.networknt.oas.model.Operation)1 Path (com.networknt.oas.model.Path)1 SecurityParameter (com.networknt.oas.model.SecurityParameter)1 SecurityRequirement (com.networknt.oas.model.SecurityRequirement)1 Status (com.networknt.status.Status)1 HeaderMap (io.undertow.util.HeaderMap)1 JwtClaims (org.jose4j.jwt.JwtClaims)1 MalformedClaimException (org.jose4j.jwt.MalformedClaimException)1 InvalidJwtException (org.jose4j.jwt.consumer.InvalidJwtException)1