播放2.5禁用某些请求的csrf保护 [英] Play 2.5 disable csrf protection for some requests

查看:148
本文介绍了播放2.5禁用某些请求的csrf保护的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆