如何在Play 2.6上禁用CSRF过滤器?

时间:2017-11-02 16:38:58

标签: scala csrf postman playframework-2.6

我一直在尝试将Postman与Play Framework API一起使用,但我一直遇到与CSRF过滤器相关的问题。

我浏览了几个论坛(包括SO)寻找修复此问题,而众所周知的建议似乎在补充:

play.filters.disabled+=play.filters.csrf.CSRFFilter

application.conf文件。

我尝试过执行该修复,但即使我这样做,我仍然在控制台日志中出现此错误:

[warn] p.filters.CSRF - [CSRF] Check failed because no token found in headers for /auth/logout

其中/auth/logout是一个POST请求,Authorization cookie设置为JWT。

我尝试过多种替代修复方法,例如将play.filters.disabled设置为[]null,允许所有主机通过CORS过滤器,所有3的各种组合等,但最终我的日志中出现了同样的错误。

唯一对应用程序进行更改的是将CSRF令牌设置为cookie而不是会话,这会将错误更改为:

[warn] p.filters.CSRF - [CSRF] Check failed because none/none for /auth/logout

这让我很高兴知道至少正确加载了application.conf,但它仍然无法解决问题。

是否有正确的方法来禁用我没有正确执行的CSRF过滤器?是否有另一种方法允许Postman通过CSRF过滤器工作?

2 个答案:

答案 0 :(得分:3)

好的,我找出了问题,但是挖掘问题的根源有点棘手。

当我将macwire添加到项目中以进行依赖注入时,我不得不定义一个自定义应用程序加载器,它需要一个自定义AppComponents类。我对AppComponents课程的声明看起来像这样:

class AppComponents(context: Context) extends BuiltInComponentsFromContext(context) with MyModule with AssetsComponents with I18nComponents with play.filters.HttpFiltersComponents

现在很明显,play.filters.HttpFiltersComponents有以下字段:

def httpFilters: Seq[EssentialFilter] = Seq(csrfFilter, securityHeadersFilter, allowedHostsFilter)

csrfFiltersecurityHeadersFilterallowedHostsFilter是有效的硬编码值。我想在使用自定义ApplicationLoader时,它会忽略application.conf文件中设置的http过滤器(这在我写这篇文章时看起来很明显)。

我正在使用的当前解决方法/修复是设置val httpFilters: Seq[EssentialFilter] = Seq(securityHeadersFilter, allowedHostsFilter),而不是默认的HttpFiltersComponents字段。我可能会稍微修改一下以从配置文件中读取过滤器,但是现在这可以解决问题。

TL; DR:在集成MacWire时添加了自定义ApplicationLoader,但没有意识到这会影响配置文件中的字段。

修改

我的ApplicationLoader中使用macwire配置HTTP过滤器的最终代码如下所示,以防其他人需要它。它使用与HttpFiltersComponents几乎完全相同的代码,但使用macwire而不是Guice(未定义的变量继承自BuiltInComponentsFromContext):

override lazy val httpFilters: Seq[EssentialFilter] = {
    val wiredInstance: Wired = wiredInModule(this)
    val classes: Seq[Class[EssentialFilter]] = {
        val disabledFilters = config.get[Seq[String]]("play.filters.disabled")
        val enabledFilters = config.get[Seq[String]]("play.filters.enabled").filterNot(disabledFilters.contains)
        try {
            for (filterClassName <- enabledFilters) yield {
                try {
                    environment.classLoader.loadClass(filterClassName).asInstanceOf[Class[EssentialFilter]]
                } catch {
                    case e: ClassNotFoundException =>
                      throw configuration.reportError("play.filters.enabled", s"Cannot load class $filterClassName", Some(e))
                }
            }
        } catch {
            case e: ConfigException.Null =>
                Nil
            case e: ConfigException.Missing =>
                Nil
        }
    }
    classes.map(x => wiredInstance.wireClassInstance(x))
}

答案 1 :(得分:0)

尝试在您的application.conf中添加以下代码:

play.filters.hosts {
  allowed = ["."]
}

让我知道它的作品适合你。 还可以查看官方游戏documentation