Search in sources :

Example 1 with RoutingContextInternal

use of io.vertx.ext.web.impl.RoutingContextInternal in project incubator-servicecomb-java-chassis by apache.

the class RestBodyHandler method handle.

@Override
public void handle(RoutingContext context) {
    HttpServerRequest request = context.request();
    if (request.headers().contains(HttpHeaders.UPGRADE, HttpHeaders.WEBSOCKET, true)) {
        context.next();
        return;
    }
    Boolean bypass = context.get(BYPASS_BODY_HANDLER);
    if (Boolean.TRUE.equals(bypass)) {
        context.next();
        return;
    }
    // we need to keep state since we can be called again on reroute
    if (!((RoutingContextInternal) context).seenHandler(RoutingContextInternal.BODY_HANDLER)) {
        long contentLength = isPreallocateBodyBuffer ? parseContentLengthHeader(request) : -1;
        BHandler handler = new BHandler(context, contentLength);
        request.handler(handler);
        request.endHandler(v -> handler.end());
        ((RoutingContextInternal) context).visitHandler(RoutingContextInternal.BODY_HANDLER);
    } else {
        // on reroute we need to re-merge the form params if that was desired
        if (mergeFormAttributes && request.isExpectMultipart()) {
            request.params().addAll(request.formAttributes());
        }
        context.next();
    }
}
Also used : HttpServerRequest(io.vertx.core.http.HttpServerRequest) RoutingContextInternal(io.vertx.ext.web.impl.RoutingContextInternal) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Example 2 with RoutingContextInternal

use of io.vertx.ext.web.impl.RoutingContextInternal in project vertx-web by vert-x3.

the class BodyHandlerImpl method handle.

@Override
public void handle(RoutingContext context) {
    HttpServerRequest request = context.request();
    if (request.headers().contains(HttpHeaders.UPGRADE, HttpHeaders.WEBSOCKET, true)) {
        context.next();
        return;
    }
    // we need to keep state since we can be called again on reroute
    if (!((RoutingContextInternal) context).seenHandler(RoutingContextInternal.BODY_HANDLER)) {
        long contentLength = isPreallocateBodyBuffer ? parseContentLengthHeader(request) : -1;
        BHandler handler = new BHandler(context, contentLength);
        request.handler(handler);
        request.endHandler(v -> handler.end());
        ((RoutingContextInternal) context).visitHandler(RoutingContextInternal.BODY_HANDLER);
    } else {
        // on reroute we need to re-merge the form params if that was desired
        if (mergeFormAttributes && request.isExpectMultipart()) {
            request.params().addAll(request.formAttributes());
        }
        context.next();
    }
}
Also used : HttpServerRequest(io.vertx.core.http.HttpServerRequest) RoutingContextInternal(io.vertx.ext.web.impl.RoutingContextInternal)

Example 3 with RoutingContextInternal

use of io.vertx.ext.web.impl.RoutingContextInternal in project vertx-web by vert-x3.

the class CSRFHandlerImpl method isValidRequest.

private boolean isValidRequest(RoutingContext ctx) {
    /* Verifying CSRF token using "Double Submit Cookie" approach */
    final Cookie cookie = ctx.request().getCookie(cookieName);
    String header = ctx.request().getHeader(headerName);
    if (header == null) {
        // fallback to form attributes
        if (((RoutingContextInternal) ctx).seenHandler(RoutingContextInternal.BODY_HANDLER)) {
            header = ctx.request().getFormAttribute(headerName);
        } else {
            ctx.fail(new IllegalStateException("BodyHandler is required to process POST requests"));
            return false;
        }
    }
    // both the header and the cookie must be present, not null and not empty
    if (header == null || cookie == null || isBlank(header)) {
        ctx.fail(403, new IllegalArgumentException("Token provided via HTTP Header/Form is absent/empty"));
        return false;
    }
    final String cookieValue = cookie.getValue();
    if (cookieValue == null || isBlank(cookieValue)) {
        ctx.fail(403, new IllegalArgumentException("Token provided via HTTP Header/Form is absent/empty"));
        return false;
    }
    final byte[] headerBytes = header.getBytes(StandardCharsets.UTF_8);
    final byte[] cookieBytes = cookieValue.getBytes(StandardCharsets.UTF_8);
    // Verify that token from header and one from cookie are the same
    if (!MessageDigest.isEqual(headerBytes, cookieBytes)) {
        ctx.fail(403, new IllegalArgumentException("Token provided via HTTP Header and via Cookie are not equal"));
        return false;
    }
    final Session session = ctx.session();
    if (session != null) {
        // get the token from the session
        String sessionToken = session.get(headerName);
        if (sessionToken != null) {
            // attempt to parse the value
            int idx = sessionToken.indexOf('/');
            if (idx != -1 && session.id() != null && session.id().equals(sessionToken.substring(0, idx))) {
                String challenge = sessionToken.substring(idx + 1);
                // the challenge must match the user-agent input
                if (!MessageDigest.isEqual(challenge.getBytes(StandardCharsets.UTF_8), headerBytes)) {
                    ctx.fail(403, new IllegalArgumentException("Token has been used or is outdated"));
                    return false;
                }
            } else {
                ctx.fail(403, new IllegalArgumentException("Token has been issued for a different session"));
                return false;
            }
        } else {
            ctx.fail(403, new IllegalArgumentException("No Token has been added to the session"));
            return false;
        }
    }
    String[] tokens = header.split("\\.");
    if (tokens.length != 3) {
        ctx.fail(403);
        return false;
    }
    byte[] saltPlusToken = (tokens[0] + "." + tokens[1]).getBytes(StandardCharsets.US_ASCII);
    synchronized (mac) {
        saltPlusToken = mac.doFinal(saltPlusToken);
    }
    final byte[] signature = base64UrlEncode(saltPlusToken).getBytes(StandardCharsets.US_ASCII);
    if (!MessageDigest.isEqual(signature, tokens[2].getBytes(StandardCharsets.US_ASCII))) {
        ctx.fail(403, new IllegalArgumentException("Token signature does not match"));
        return false;
    }
    // this token has been used and we discard it to avoid replay attacks
    if (session != null) {
        session.remove(headerName);
    }
    final long ts = parseLong(tokens[1]);
    if (ts == -1) {
        ctx.fail(403);
        return false;
    }
    // validate validity
    if (System.currentTimeMillis() > ts + timeout) {
        ctx.fail(403, new IllegalArgumentException("CSRF validity expired"));
        return false;
    }
    return true;
}
Also used : Cookie(io.vertx.core.http.Cookie) RoutingContextInternal(io.vertx.ext.web.impl.RoutingContextInternal) Session(io.vertx.ext.web.Session)

Example 4 with RoutingContextInternal

use of io.vertx.ext.web.impl.RoutingContextInternal in project java-chassis by ServiceComb.

the class RestBodyHandler method handle.

@Override
public void handle(RoutingContext context) {
    HttpServerRequest request = context.request();
    if (request.headers().contains(HttpHeaders.UPGRADE, HttpHeaders.WEBSOCKET, true)) {
        context.next();
        return;
    }
    Boolean bypass = context.get(BYPASS_BODY_HANDLER);
    if (Boolean.TRUE.equals(bypass)) {
        context.next();
        return;
    }
    // we need to keep state since we can be called again on reroute
    if (!((RoutingContextInternal) context).seenHandler(RoutingContextInternal.BODY_HANDLER)) {
        long contentLength = isPreallocateBodyBuffer ? parseContentLengthHeader(request) : -1;
        BHandler handler = new BHandler(context, contentLength);
        request.handler(handler);
        request.endHandler(v -> handler.end());
        ((RoutingContextInternal) context).visitHandler(RoutingContextInternal.BODY_HANDLER);
    } else {
        // on reroute we need to re-merge the form params if that was desired
        if (mergeFormAttributes && request.isExpectMultipart()) {
            request.params().addAll(request.formAttributes());
        }
        context.next();
    }
}
Also used : HttpServerRequest(io.vertx.core.http.HttpServerRequest) RoutingContextInternal(io.vertx.ext.web.impl.RoutingContextInternal) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean)

Aggregations

RoutingContextInternal (io.vertx.ext.web.impl.RoutingContextInternal)4 HttpServerRequest (io.vertx.core.http.HttpServerRequest)3 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)2 Cookie (io.vertx.core.http.Cookie)1 Session (io.vertx.ext.web.Session)1