Sie können CSRFFilter
dekorieren und eine Liste von Routenpfaden verwenden, um die Anwendung des Filters ein- oder auszuschließen.
Die Routenweg müssen in der kompilierten Form sein, so dass eine Route, wie '/ foo/bar' /profile
würde aber eine Route mit dynamischen Komponenten wie /view/:foo/:bar
/view/$foo<[^/]+>/$bar<[^/]+>
wird sein. Sie können die kompilierten Versionen der Routen auflisten, indem Sie im Entwicklungsmodus eine nicht zugeordnete URL aufrufen (z. B.).
import java.util.LinkedList;
import java.util.List;
import javax.inject.Inject;
import akka.util.ByteString;
import play.filters.csrf.CSRFFilter;
import play.libs.streams.Accumulator;
import play.mvc.EssentialAction;
import play.mvc.EssentialFilter;
import play.mvc.Result;
import play.routing.Router;
public class MaybeCsrfFilter extends EssentialFilter {
private final EssentialFilter csrfFilter;
private final List<String> applyCsrf = new LinkedList<>();
@Inject
public MaybeCsrfFilter(final CSRFFilter csrfFilter) {
this.csrfFilter = csrfFilter.asJava();
// alternatively, define the inclusion/exclusion list in the config and inject Configuration to obtain it
applyCsrf.add("/foo/bar");
applyCsrf.add("/view/$foo<[^/]+>/$bar<[^/]+>");
}
@Override
public EssentialAction apply(final EssentialAction next) {
return EssentialAction.of(request -> {
final Accumulator<ByteString, Result> accumulator;
final String currentRoute = request.tags().get(Router.Tags.ROUTE_PATTERN);
if (applyCsrf.contains(currentRoute)) {
accumulator = csrfFilter.apply(next).apply(request);
} else {
accumulator = next.apply(request);
}
return accumulator;
});
}
}
Es ist rohe Gewalt, und Sie haben Ihre Filter synchron mit der Ein-/Ausschlussliste zu halten, aber es funktioniert.
Alternativ können Sie Kommentare in der Datei routes
verwenden, um zu bestimmen, auf welchen Routen der CSRF-Filter nicht angewendet werden soll.
Für eine routes
Datei wie
#NOCSRF
GET /foo/bar controllers.Application.foo()
#NOCSRF
GET /view/:hurdy/:gurdy controllers.Application.bar()
GET /something/else controllers.Application.bar()
Dieser Filter Implementierung wird die CSRF-Filter auf jede Aktion, deren Weg durch # NOCSRF
keine Anwendung voraus. In diesem Beispiel wird nur der Filter CSRF auf /something/else
angewendet.
public EssentialAction apply(final EssentialAction next) {
return EssentialAction.of(request -> {
final Accumulator<ByteString, Result> accumulator;
final String routeComment = request.tags().get(Router.Tags.ROUTE_COMMENTS);
if ("NOCSRF".equals(routeComment)) {
accumulator = next.apply(request);
} else {
accumulator = csrfFilter.apply(next).apply(request);
}
return accumulator;
});
}
Ihre Filters
Definition dann wird
public class Filters implements HttpFilters {
private final MaybeCsrfFilter csrf;
@Inject
public Filters(final MaybeCsrfFilter csrf) {
this.csrf = csrf;
}
@Override
public EssentialFilter[] filters() {
return new EssentialFilter[]{csrf};
}
}
keine bindende für MaybeCsrfFilter
erstellen Vergessen!
Es gibt noch ein Problem, das CSRF für bestimmte Routen deaktiviert: https://github.com/playframework/playframework/issues/5882 – adis