All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jetdrone.vertx.yoke.middleware.Csrf Maven / Gradle / Ivy

There is a newer version: 3.0.0
Show newest version
/**
 * Copyright 2011-2014 the original author or authors.
 */
package com.jetdrone.vertx.yoke.middleware;

import com.jetdrone.vertx.yoke.Middleware;
import org.jetbrains.annotations.NotNull;
import org.vertx.java.core.Handler;

import java.util.UUID;

/**
 * # Csrf
 *
 * This middleware adds a CSRF token to requests which mutate state. You should put the result within a hidden form
 * field, query-string etc. This token should be validated against the visitor's session.
 * The default value handler checks request body generated by the BodyParser middleware, request query generated and
 * the "X-CSRF-Token" header field.
 *
 * This middleware requires session support, thus should be added somewhere below Session.
 */
public class Csrf extends Middleware {

    /**
     * Handler that validates the CRSF token
     */
    private final ValueHandler valueHandler;

    /**
     * Name of the property where the token is found/stored in the request context
     */
    private final String key;

    /**
     * Instantiate a new Csrf with a user defined key
     *
     * 
     * new Csrf("_crsf")
     * 
* * @param key name of the context variable to store the token. */ public Csrf(@NotNull final String key) { this.key = key; valueHandler = new ValueHandler() { @Override public String handle(YokeRequest request) { String token = request.formAttributes().get(key); if (token == null) { token = request.params().get(key); if (token == null) { token = request.headers().get("x-csrf-token"); } } return token; } }; } /** * Instantiate a new Csrf with the default key "_crsf" * *
     * new Csrf()
     * 
*/ public Csrf() { this("_csrf"); } /** * Instantiate a new Csrf with custom Handler and key * *
     * new Csrf("_crsf", new ValueHandler() {...})
     * 
* * @param key name of the context variable to store the token. * @param valueHandler the handler for the token validation. */ public Csrf(@NotNull String key, @NotNull ValueHandler valueHandler) { this.key = key; this.valueHandler = valueHandler; } /** * Instantiate a new Csrf with custom Handler * *
     * new Csrf(new ValueHandler() {...})
     * 
* * @param valueHandler the handler for the token validation. */ public Csrf(@NotNull final ValueHandler valueHandler) { this("_csrf", valueHandler); } public interface ValueHandler { String handle(YokeRequest request); } @Override public void handle(@NotNull final YokeRequest request, @NotNull final Handler next) { String token = request.get(key); // generate CSRF token if (token == null) { token = UUID.randomUUID().toString(); request.put(key, token); } // ignore these methods if ("GET".equals(request.method()) || "HEAD".equals(request.method()) || "OPTIONS".equals(request.method())) { next.handle(null); return; } // expect multipart request.expectMultiPart(true); // determine value String val = valueHandler.handle(request); // check if (!token.equals(val)) { next.handle(403); return; } // OK next.handle(null); } }