Java 播放框架CSRF错误“;[CSRF]检查失败,因为在标头中找不到令牌;
我是游戏框架中的新手,正在尝试提交表单,但是 获取此错误:“p.filters.CSRF-[CSRF]检查失败,因为在标头中找不到令牌”。我正在使用Play 2.6,以下是我的控制器代码:Java 播放框架CSRF错误“;[CSRF]检查失败,因为在标头中找不到令牌;,java,playframework,Java,Playframework,我是游戏框架中的新手,正在尝试提交表单,但是 获取此错误:“p.filters.CSRF-[CSRF]检查失败,因为在标头中找不到令牌”。我正在使用Play 2.6,以下是我的控制器代码: package controllers; import play.libs.Json; import play.mvc.*; import views.html.*; import java.util.ArrayList; import java.util.List; import java.u
package controllers;
import play.libs.Json;
import play.mvc.*;
import views.html.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class HomeController extends Controller {
public Result index() {
return ok(index.render("Your new application is ready."));
}
public Result test() {
List<String> list = new ArrayList<>();
list.add("Jobs");
list.add("Work");
list.add("Say");
list.add("Stop");
return ok(test.render("test", list));
}
public Result testPost() {
Map<String,String[]> form = request().body().asFormUrlEncoded();
return ok(Json.toJson(form)).as("application/json");
}
}
包控制器;
导入play.libs.Json;
导入play.mvc.*;
导入视图;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Map;
公共类HomeController扩展控制器{
公开结果索引(){
返回ok(index.render(“新应用程序准备就绪”);
}
公开结果测试(){
列表=新的ArrayList();
列表。添加(“工作”);
列表。添加(“工作”);
列表。添加(“说”);
列表。添加(“停止”);
返回ok(test.render(“test”,list));
}
公共结果testPost(){
映射表单=请求().body().asFormUrlEncoded();
返回ok(Json.toJson(form)).as(“application/Json”);
}
}
模板:
@(title: String, list: List[String])
@import helper._
<!DOCTYPE html>
<html lang="en">
<head>
<title>@title</title>
</head>
<body>
<form action="/test" method="post">
<textarea name="raw_text">
</textarea>
@CSRF.formField
<input type="submit" value="Submit" />
</form>
</body>
</html>
@(标题:字符串,列表:列表[字符串])
@导入助手_
@头衔
@CSRF.formField
我做错了什么?我找不到你的代码有任何错误,所以在本地设置一个相同的播放项目。 提交表单时,我没有碰到这个问题。 这是通过以下方式创建的基础项目:
sbt new playframework/play-java-seed.g8
将“Testing Testing”作为textArea的内容发布将返回以下Json(如浏览器所示):
我从自己的项目中得到的一个东西是修改后的Filters类,如下所示:
import play.mvc.EssentialFilter;
import play.filters.cors.CORSFilter;
import play.http.HttpFilters;
import play.filters.csrf.CSRFFilter;
import play.filters.headers.SecurityHeadersFilter;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.Arrays;
public class Filters implements HttpFilters {
@Inject
CSRFFilter csrfFilter;
@Inject
CORSFilter corsFilter;
@Inject
SecurityHeadersFilter secHeaders;
@Override
public List<EssentialFilter> getFilters() {
return Arrays.<EssentialFilter>asList(new EssentialFilter[] { corsFilter.asJava(),secHeaders.asJava(), csrfFilter.asJava()});
}
}
删除@CSRF.formField会导致与您一样的未经授权的CSRF
如果您的设置有任何明显的差异,我很乐意进一步挖掘,但这似乎不是您的代码的直接问题。我已经遇到了它。我很简单地解决了这个问题。只需添加到application.conf: 在路由文件中,在路由之前添加nocsrf修改器标记:
+nocsrf
POST /login controllers.AuthController.authorize()
就这样。。
我希望我的回答能帮助你。谢谢大家! 这可能不适用于所有情况,但在我的情况下,原因是我正在控制器中重置会话,因此CSRF令牌以某种方式变得无效
如果您在代码中调用“withNewSession”时出现此错误,请尝试将其删除,然后查看错误是否消失。杜曼·詹博拉托夫的回答是错误的。是的,这样做可以避免错误,但这不是答案。它会将应用程序推向安全漏洞 应用程序面临问题的原因是表单页面请求的播放会话(或您自定义的会话名称)cookie为空,其中csrfToken=value应该被加密。因为cookies中的csrfToken=value已被删除。如果发送带有新会话或丢弃cookie的响应,则可能会发生这种情况。 因此,如果您放弃cookie或使用新会话发送响应,请使用csrfToken=valuesession发送响应
def logout: Action[AnyContent] = Action {
implicit request =>
val csrfToken = CSRF.getToken.get.value
Ok(logIn("Please log in")).withNewSession.withSession("csrfToken"->csrfToken)
}
那你就可以解决这个问题了 我用同样的方法创建了这个项目,现在一切都很好。但是,当我在这里使用play java starter示例时,仍然会出现此错误。那么,这可能是一个筛选器配置问题,请参阅下面的页面:“如果您已经了解Play并希望立即创建新项目,那么这是一个不错的选择。请注意,seed模板已经配置了CSRF和security headers过滤器,而其他项目并没有专门针对开箱即用的安全性进行设置。“明天我会看看基地的设置。应答中的Sbt命令使用种子模板。干杯。我对从play-scala-seed.g8模板创建的scala项目也有同样的问题。我按照文档中的规定传递了CSRF令牌,但未经授权,在控制台中我看到:p.a.m.DefaultJWTCookieDataCodec-decode:无法解码JWT:JWT签名与本地计算的签名不匹配。无法断言JWT有效性,不应信任JWT有效性。io.jsonwebtoken.SignatureException:JWT签名与本地计算的签名不匹配。无法断言JWT有效性,不应信任JWT有效性,[CSRF]检查失败,因为在标头中找不到令牌。我使用了@CSRF.formField东西。好的,它在我重新启动play-怪异后开始工作。
/login
听起来此控制器将从用户处接收表单。在该路线上禁用CSRF过滤器会破坏使用该过滤器的目的。但当这是一个受到其他保护的API端点时,它非常方便。如果其他人刚刚使用剪影框架遇到此问题,您至少可以使用此答案来确认是否可以绕过此问题。在我的情况下,POST/signIn
call令人窒息。一旦发布了新的会话令牌,就不会再有问题了。
play.filters.enabled += "play.filters.csrf.CSRFFilter"
+nocsrf
POST /login controllers.AuthController.authorize()
def logout: Action[AnyContent] = Action {
implicit request =>
val csrfToken = CSRF.getToken.get.value
Ok(logIn("Please log in")).withNewSession.withSession("csrfToken"->csrfToken)
}