Playframework с CSRF: «токен CSRF не найден в сеансе»?

Я делаю простую систему аутентификации, используя Playframework со встроенным CSRF-фильтром и системой Security.Authenticator, но я столкнулся с проблемой:

Когда пользователь вводит свой логин / пароль и отправляет ввод, у меня появляется следующая ошибка:

Маркер CSRF не найден в сеансе

Я проверил свою форму и токен CSRF действительно присутствует и правильно размещен (внутри тега)

Вот мойroutes :

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

И мойAuthentication.java учебный класс :

@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]">Email:</label>
            <input type="email" name="@element.name" id="[email protected]" 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]">Password:</label>
            <input type="password" name="@element.name" id="[email protected]" 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>

Обновление 1: Я удалил все@addCSRFToken а также@requireCSRFToken и вместо этого определил глобальный токен CSRF в соответствии с рекомендацией @rhj. Теперь я получил эту ошибку вместо:

В теле формы найден неверный токен

Но, как вы можете видеть в HTML-форме, токен находится внутри формы и должен быть идентифицирован!

Обновление 2: Больше всего меня беспокоит то, что эта проблема возникает только на странице входа в систему, а не где-либо еще! Есть ли какой-то сеанс, чтобы включить сначала? Я думаю, нет, но, может быть, ?!

Обновление 3: Более странно, я только что узнал, что если я изменю значениеcsrf.token.name и перезагрузите страницу, все работает. Затем, если я выйду из системы, открою новую страницу и попытаюсь снова войти в систему, произойдет сбой с сообщениемInvalid token found in form body, Если я снова изменю значениеcsrf.token.name и сделайте это снова, это будет работать снова.

Обновление 4Я сузил проблему. Я также использую play.mvc.Security.Authenticator, и кажется, что проверка токена завершается неудачно ТОЛЬКО при отображении страницы послеredirect(), Если я перейду прямо к странице входа, у меня не будет отображаться сообщение об ошибке.

Финальное обновление! Я наконец нашел проблему, это было в другом классе, который я не подозревал, который был вызван и очистил сеанс, делая токен бесполезным!

Ответы на вопрос(2)

Ваш ответ на вопрос