播放2.5禁用某些请求的csrf保护 [英] Play 2.5 disable csrf protection for some requests
问题描述
我正在使用play framework v.2.5.3编写我的应用程序并使用官方文档中描述的CSRF保护。
I'm writing my app using play framework v. 2.5.3 and use CSRF protection as it is described in official documentation.
public class Filters implements HttpFilters {
@Inject
CSRFFilter csrfFilter;
@Override
public EssentialFilter[] filters() {
return new EssentialFilter[]{csrfFilter.asJava()};
}}
当然,只要所有请求都需要,它就可以工作过滤,但其中一些应该被绕过。如何配置过滤器以绕过某些指定路由的请求?谢谢你的帮助!
Of course, it works, as long as all of requests need to be filtered, but some of them should be bypassed. How can filters be configured to bypass requests to some specified route? Thanks for your help!
推荐答案
您可以装饰 CSRFFilter
并使用路径路径列表包含或排除过滤器的应用。
You can decorate CSRFFilter
and use a list of route paths to either include or exclude the application of the filter.
路径路径需要采用编译形式,因此像'/ foo / bar'这样的路径将是 / profile
但是包含 / view /:foo /:bar
等动态组件的路由变为 /视图/ $ foo的百分比抑制率数据^ /] + GT; / $巴≤; [^ /] + GT;
。在开发模式下,您可以通过转到未映射的URL(例如 http:// localhost:9000 / @ foo
)来列出路由的编译版本。
The route paths will need to be in the compiled form, so a route like ´/foo/bar´ would be /profile
but a route with dynamic components like /view/:foo/:bar
becomes /view/$foo<[^/]+>/$bar<[^/]+>
. You can list the compiled versions of the routes by going to an unmapped URL (e.g. http://localhost:9000/@foo
) when in development mode.
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;
});
}
}
这是蛮力,你必须保留过滤器与包含/排除列表同步,但它可以工作。
It's brute force, and you have to keep your filters in sync with the inclusion/exclusion list, but it works.
或者,你可以在 routes中使用注释
文件以确定哪些路由不应该应用CSRF过滤器。
Alternatively, you can use comments in the routes
file to determine which routes should not have the CSRF filter applied.
对于路由
文件,如
#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过滤器。
This filter implementation will not apply the CSRF filter to any action whose route is preceded by # NOCSRF
. For this example, only /something/else
will have the CSRF filter applied to it.
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;
});
}
您的过滤器
定义然后变成
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};
}
}
不要忘记为<$创建绑定c $ c> MaybeCsrfFilter !
这篇关于播放2.5禁用某些请求的csrf保护的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!