Playframework 与 CSRF:“会话中未找到 CSRF 令牌”?

2024-03-04

我正在使用 Playframework 及其内置 CSRF 过滤器和 Security.Authenticator 系统制作一个简单的身份验证系统,但我遇到了一个问题:

当用户填写登录名/密码并提交输入时,出现以下错误:

在会话中找不到 CSRF 令牌

我检查了我的表单,CSRF 令牌确实存在并且正确放置(在标签内)

这是我的routes :

GET     /login                      controllers.Authentication.login
POST    /login                      controllers.Authentication.authenticate

And my Authentication.java class :

@play.filters.csrf.AddCSRFToken
public static Result login() {
    if (Session.getAccount() != null) {
        return redirect(controllers.routes.Instances.list());
    }

    LoginForm loginForm = new LoginForm();
    if (ctx().session().containsKey("email")) {
        loginForm.setEmail(ctx().session().get("email"));
    }

    if (request().queryString().containsKey("disconnected")) {
        flash("warning", Messages.get("secure.logout")); // TODO : Warning flash message
    }

    Form<LoginForm> form = Form.form(LoginForm.class).fill(loginForm);
    return ok(views.html.login.render(form));
}

@play.filters.csrf.AddCSRFToken
@play.filters.csrf.RequireCSRFCheck
public static Result authenticate() {
    Form<LoginForm> form = Form.form(LoginForm.class).bindFromRequest();
    if (form.hasErrors()) {
        return badRequest(views.html.login.render(form));
    }

    LoginForm login = form.get();
    Account account = Account.findByEmail(login.getEmail());

    if (account == null || !account.checkPassword(login.getPassword())) {
        form.reject("email", "secure.invalid.login");
        return badRequest(views.html.login.render(form));
    }

    String next = null;
    if (ctx().session().containsKey("next")) {
        next = ctx().session().get("next");
        if ("".equals(next)) {
            next = null;
        }
    }

    session().clear();
    session("email", login.getEmail());

    if (next != null) {
        return redirect(next);
    } else {
        return redirect(controllers.routes.Instances.list());
    }
}

我在 application.conf 中设置的属性:

csrf.token.name="csrf"
csrf.sign.tokens=true

这是我的表单(以表明令牌位置正确):

<form action="@controllers.routes.Authentication.authenticate" method="post" class="form-vertical" role="form">
    <fieldset>
        @defining(form("email")) { element =>
        <div class="form-group fade-in two@if(element.hasErrors){ has-error}">
            <label class="control-label" for="[email protected] /cdn-cgi/l/email-protection">Email:</label>
            <input type="email" name="@element.name" id="[email protected] /cdn-cgi/l/email-protection" class="form-control" value="@element.value" placeholder="Enter your email" required />
            @element.errors.map { error => <span class="help-block">@play.i18n.Messages.get(error.message)</span>}
        </div>}
        @defining(form("password")) { element =>
        <div class="form-group fade-in three@if(element.hasErrors){ has-error}">
            <label class="control-label" for="[email protected] /cdn-cgi/l/email-protection">Password:</label>
            <input type="password" name="@element.name" id="[email protected] /cdn-cgi/l/email-protection" class="form-control" value="@element.value" placeholder="Enter your password" required />
            @element.errors.map { error => <span class="help-block">@play.i18n.Messages.get(error.message)</span>}
        </div>}
        <div class="form-group actions fade-in four">
            <div class="text-right">
                <input type="submit" name="save" value="Sign me in" class="btn btn-primary" />
                @helper.CSRF.formField
            </div>
        </div>
    </fieldset>
</form>

Update 1: 我把所有的都删掉了@addCSRFToken and @requireCSRFToken并根据 @rhj 的建议定义了一个全局 CSRF 令牌。现在我得到了这个错误:

在表单正文中发现无效令牌

但正如您在 HTML 表单中看到的那样,令牌放置在表单内部,应该可以被识别!

Update 2:最让我烦恼的是,这个问题只出现在登录页面,其他地方都没有!是否需要先启用一些会话?我想不会,但也许吧?!

Update 3:更奇怪的是,我刚刚发现如果我改变的值csrf.token.name并重新加载页面,它就可以工作了。然后,如果我注销,打开一个新页面并尝试再次登录,则会失败并显示以下消息Invalid token found in form body。如果我再次改变值csrf.token.name再做一次,它就会再次起作用。

Update 4: 我缩小了问题范围。我还使用 play.mvc.Security.Authenticator,似乎令牌验证仅在我在redirect()。如果我直接进入登录页面,则不会显示错误消息。

最后更新!:我终于找到了问题,它是在另一个我没有怀疑的类中,它被调用并清除了会话,使令牌变得无用!


最后,问题出现在我的代码的另一部分,该部分正在清理会话中的会话login()方法,用它删除 csrf 令牌...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Playframework 与 CSRF:“会话中未找到 CSRF 令牌”? 的相关文章

  • 如何通过 SSL 使用 Play WS?

    我的 Java 客户端应用程序需要执行 REST 调用 我被指示使用 Play 的 WS 实现 目前 我有这个 AsyncHttpClientConfig Builder builder new com ning http client A
  • Playframework:如何在不同项目之间共享模型?

    我想与其他一些项目共享我的模型 他们使用相同的模型 但不使用相同的字段映射和约束 我想知道是否有办法从模型中提取注释并使用 xml 配置代替 或者其他方式来实现这一目标 注意 我正在使用play 1 3 上周我正在分析类似的事情 存档的一种
  • Actor 中的 WebSocket.acceptWithActor 和 @Inject()(播放 2.5)

    WebSocket acceptWithActor不使用 Guice 实例化一个新的 Akka actor 在 Play 2 4 中 仍然可以通过导入来为我的 actor 使用注入器play api Play current 片段来自Rea
  • DdlGenerator 构造函数不需要参数?

    我想对我的数据库操作进行单元测试 我发现这段代码 https gist github com nboire 2819920 但是 我收到以下错误 CityGame test info Compiling 2 Java sources to
  • 大数据请求体为空

    我在 post 方法的正文中发送大量文本 我使用 Postman 来测试这一点 但是它工作正常 我可以像这样读取请求正文 String text request body asText 但是当我尝试在正文中发送大量数据时 我得到的文本为空
  • 在 MVC 框架中将 noSQL 和 ORM 结合起来用于实际案例应用程序

    一段时间以来 我一直在尝试将过去几年中读到的一些有关 noSQL couchDB mongoDB Redis 的 酷 东西投入实际使用 我非常习惯使用 Django 编写应用程序 并开始使用 Play 当 Java 是唯一可接受的部署选项
  • Play框架2.5.0 Websockets示例[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 播放框架 2 5 0 Websockets 示例 在 play 2 5 0 websockets 代码
  • 为什么 Scala 程序的编译速度非常慢?

    过去两个月我一直在使用 Scala 我还在一个小应用程序中使用 Play 框架 我观察到 即使对于打印 Hello World 的程序来说 编译也非常慢 为什么这么慢 有什么减少时间的技巧吗 您的情况下编译速度有多快 scalac 的速度受
  • 使用 JsonView 将 POJO 转换为 JsonNode

    我正在编写一个典型的 Play Framework 应用程序 我想使用 Jackson 从控制器的方法返回 JsonNode 这就是我现在正在做的 public static Result foo MyPojoType myPojo new
  • Ruby on Rails Devise Oauth-facebook OmniAuth::Strategies::OAuth2::CallbackError

    我使用 facebook 实现 oauth 登录并设计 当从接受应用程序 弹出窗口 返回时 我收到以下错误 由于 检测到 Csrf 无法通过 Facebook 验证您的身份 这是日志 于 2014 01 23 23 59 58 0100 开
  • 播放框架 Ebean BigDecimal 分数

    我正在使用带有 Ebean 和 H2 数据库的 Play 框架 问题是 BigDecimalDB 脚本的结果为 sum decimal 38 但我想要的是 sum decimal 38 2 我已经尝试像这样定义模型中的值 Digits in
  • sbt-proguard 与 play 2.2.3

    我们使用 play 2 2 3 开发了一个 Web 应用程序 并希望对其进行混淆 我正在尝试使用sbt proguard https github com sbt sbt proguard插入 我把下面的行PROJECT FOLDER pr
  • sbt 程序集中的合并策略和缺少的应用程序加载器

    我正在开发一个 Play Web 应用程序 我希望能够使用 sbt 程序集将其部署为 fat jar 在调试中运行应用程序时 我可以识别 guice 库 因为它已添加到我的 build sbt 文件中 libraryDependencies
  • Play2 的异常无法在 postgresql 上运行

    我发现play2的anorm的行解析器依赖于jdbc驱动程序返回的元数据 所以在play提供的内置示例 zentasks 中 我可以找到这样的代码 object Project val simple get Pk Long project
  • Play async/await 中会话/上下文丢失

    看来await 方法失去上下文 public static action session put key value await someAsyncCall Now for some reason the session doesn t h
  • 使用 Play WS 并获取 java.net.ConnectException:Amazon Cloudfront 上的握手超时

    在我的 Play 应用程序中 我需要从 Amazon Cloudfront 下载大量文件 使用 SSL 我在链接上随机收到以下错误 play api http HttpErrorHandlerExceptions anon 1 Execut
  • 在scala / play框架中构建Json文件

    我正在使用 Play 框架和 Scala 我需要提供一个如下所示的输入 id node37 name 3 7 data children 如何使用 json 获取该格式 以下是 Play 框架网站上的示例 val JsonObject Js
  • 清理 IntelliJ 中构建的 Play 框架

    我有一个拼写错误conf routes文件导致 Play Framework 生成错误命名的类 重建项目并运行Invalidate Caches并没有解决 IntelliJ 中的问题 当我手动运行时重新生成了不正确的类文件play clea
  • Play框架:单属性案例类的JSON读取

    我正在尝试为包含单个属性的案例类创建隐式 JSON Reads 但收到错误 Reads Nothing 不符合预期类型 这是代码 import play api libs functional syntax import play api
  • 如何使用play框架上传多个文件?

    我在用play framework 2 1 2 使用java我正在创建视图来上传多个文件 我的代码在这里 form action routes upload up enctype gt multipart form data

随机推荐