Playframework con CSRF: “¿El token CSRF no se encuentra en la sesión”?

Estoy haciendo un sistema de autenticación simple usando Playframework con su filtro CSRF incorporado y el sistema de seguridad. Autenticador, pero estoy enfrentando un problema:

Cuando el usuario llena su nombre de usuario / contraseña y envía enter, tengo el siguiente error:

Token CSRF no encontrado en la sesión

Revisé mi formulario y el token CSRF está realmente presente y colocado correctamente (dentro de la etiqueta)

Aquí está miroutes :

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

Y miAuthentication.java clase :

@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());
    }
}

Las propiedades que configuré en la aplicación.conf:

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

Aquí está mi formulario (para mostrar que el token está correctamente colocado):

<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>

Actualización 1: Eliminé todos los@addCSRFToken y@requireCSRFToken y definió un token CSRF global en su lugar, según la recomendación de @rhj. Ahora recibí este error en su lugar:

Token no válido encontrado en el cuerpo del formulario

Pero como puede ver en el formulario HTML, el token se coloca dentro del formulario y debe identificarse.

Actualización 2: ¡Lo que más me molesta es que este problema solo ocurre en la página de inicio de sesión y no en otro lugar! ¿Hay alguna sesión para habilitar primero? Supongo que no, pero tal vez?

Actualización 3: Más extraño, acabo de descubrir que si cambio el valor decsrf.token.name y vuelve a cargar la página, funciona. Luego, si me desconecto, abro una nueva página e intento iniciar sesión nuevamente, falla con el mensajeInvalid token found in form body. Si vuelvo a cambiar el valor decsrf.token.name y hacerlo de nuevo, funcionará de nuevo.

Actualización 4: Reduje el problema. También utilizo play.mvc.Security.Authenticator y parece que la verificación del token falla SOLO cuando visualizo la página después de unredirect(). Si voy directamente a la página de inicio de sesión, no se mostrará el mensaje de error.

Actualización final! : Finalmente encontré el problema, fue en otra clase de la que no sospechaba, se llamó y borró la sesión, ¡haciendo que el token fuera inútil!

Respuestas a la pregunta(2)

Su respuesta a la pregunta