gpt4 book ai didi

java - Play 2.5 对某些请求禁用 csrf 保护

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:38:31 27 4
gpt4 key购买 nike

我正在使用 play framework v. 2.5.3 编写我的应用程序,并使用官方文档中描述的 CSRF 保护。

public class Filters implements HttpFilters {

@Inject
CSRFFilter csrfFilter;

@Override
public EssentialFilter[] filters() {
return new EssentialFilter[]{csrfFilter.asJava()};
}}

当然,它可以工作,只要所有请求都需要被过滤,但其中一些应该被绕过。如何配置过滤器以绕过某些指定路由的请求?感谢您的帮助!

最佳答案

你可以装饰CSRFFilter并使用路由路径列表来包含或排除过滤器的应用。

路由路径需要采用编译形式,因此像“/foo/bar”这样的路由将是 /profile但是带有动态组件的路由,如 /view/:foo/:bar变成 /view/$foo<[^/]+>/$bar<[^/]+> .在开发模式下,您可以通过转到未映射的 URL(例如 http://localhost:9000/@foo)列出路由的编译版本。

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;
});
}
}

这是蛮力,您必须使您的过滤器与包含/排除列表保持同步,但它有效。

或者,您可以在 routes 中使用注释文件以确定哪些路由不应应用 CSRF 过滤器。

对于 routes像这样的文件

#NOCSRF
GET /foo/bar controllers.Application.foo()
#NOCSRF
GET /view/:hurdy/:gurdy controllers.Application.bar()
GET /something/else controllers.Application.bar()

此过滤器实现不会将 CSRF 过滤器应用于其路由以 # NOCSRF 开头的任何操作.对于这个例子,只有 /something/else将应用 CSRF 过滤器。

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;
});
}

你的 Filters定义就变成了

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};
}
}

不要忘记为 MaybeCsrfFilter 创建一个绑定(bind)!

关于java - Play 2.5 对某些请求禁用 csrf 保护,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37408269/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com