我一直在尝试将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过滤器工作?
答案 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)
csrfFilter
,securityHeadersFilter
和allowedHostsFilter
是有效的硬编码值。我想在使用自定义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。