When a second (or later subsequent) authentication attempt arrives on an already authenticated session and session attribute migration is disabled the security context is not always persisted to the new session.
With an existing authenticated session, subsequent POST requests to the form-login login-processing url will destroy the old session and create a new session. Occasionally the hash code of the persisted security context does not change and so the HttpSecurityContextRepository does not "update" the context stored in the session. The problem is that the old session held the unchanged security context but the new session does not hold any security context. After successfully authenticating another authentication is required because the new session does not contain a SecurityContext.
One factor causing the HttpSecurityContextRepository to not update/store the SecurityContext is that the session id stored in the security context is the old session id, even after that session has been destroyed and a new one created to replace it. This allows the SecurityContext hashCode to remain the same even though some aspect of the SecurityContext has indeed changed.
The check to set the security context attribute in HttpSecurityContextRepository.SaveToSessionResponseWrapper.saveContext should probably include something to ensure that the current session actually does contain the context, whether it has changed or not. In the case that the context has not changed, but the session has, the context should be stored to the new session.