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

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

问题描述

我正在使用 play 框架 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 变成 /view/$foo<[^/]+>/$bar<[^/]+>.在开发模式下,您可以通过访问未映射的 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.

对于 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 过滤器.

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

你的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 创建绑定!

Don't forget to create a binding for MaybeCsrfFilter!

这篇关于Play 2.5 对某些请求禁用 csrf 保护的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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