Después de que un nuevo usuario envía un formulario de 'Nueva cuenta', quiero iniciar sesión manualmente con ese usuario para que no tenga que iniciar sesión en la página siguiente.
La página de inicio de sesión de formulario normal que pasa por el interceptor de seguridad de primavera funciona bien.
En el controlador de formulario de cuenta nueva, estoy creando un UsernamePasswordAuthenticationToken y configurándolo en SecurityContext manualmente:
SecurityContextHolder.getContext().setAuthentication(authentication);
En esa misma página, luego verifico que el usuario haya iniciado sesión con:
SecurityContextHolder.getContext().getAuthentication().getAuthorities();
Esto devuelve las autoridades que establecí anteriormente en la autenticación. Todo está bien.
Pero cuando se llama a este mismo código en la página siguiente que cargo, el token de autenticación es solo UserAnonymous.
No tengo claro por qué no mantuvo la autenticación que configuré en la solicitud anterior. ¿Alguna idea?
- ¿Podría tener que ver con que los ID de sesión no están configurados correctamente?
- ¿Hay algo que posiblemente esté sobrescribiendo mi autenticación de alguna manera?
- ¿Quizás solo necesito otro paso para guardar la autenticación?
- ¿O hay algo que deba hacer para declarar la autenticación en toda la sesión en lugar de una sola solicitud de alguna manera?
Solo busco algunas ideas que puedan ayudarme a ver lo que está sucediendo aquí.
fuente
SecurityContextHolder.getContext().setAuthentication(authentication)
. Funciona y es común, pero existen serias deficiencias de funcionalidad que encontrará si lo hace. Para obtener más información, consulte mi pregunta y la respuesta: stackoverflow.com/questions/47233187/…Respuestas:
Tuve el mismo problema que tú hace un tiempo. No recuerdo los detalles, pero el siguiente código hizo que las cosas me funcionaran. Este código se usa dentro de un flujo de Spring Webflow, de ahí las clases RequestContext y ExternalContext. Pero la parte que es más relevante para usted es el método doAutoLogin.
fuente
@Configuration public class WebConfig extends WebSecurityConfigurerAdapter { @Bean @Override public AuthenticationManager authenticationProvider() throws Exception { return super.authenticationManagerBean(); } }
No pude encontrar ninguna otra solución completa, así que pensé en publicar la mía. Esto puede ser un truco, pero resolvió el problema anterior:
fuente
authenticationManager
a partir?Finalmente descubrió la raíz del problema.
Cuando creo el contexto de seguridad manualmente, no se crea ningún objeto de sesión. Solo cuando la solicitud termina de procesarse, el mecanismo de Spring Security se da cuenta de que el objeto de sesión es nulo (cuando intenta almacenar el contexto de seguridad en la sesión después de que se haya procesado la solicitud).
Al final de la solicitud, Spring Security crea un nuevo objeto de sesión e ID de sesión. Sin embargo, esta nueva ID de sesión nunca llega al navegador porque ocurre al final de la solicitud, después de que se haya dado la respuesta al navegador. Esto hace que la nueva ID de sesión (y por lo tanto el contexto de seguridad que contiene mi usuario que inició sesión manualmente) se pierda cuando la siguiente solicitud contiene la ID de sesión anterior.
fuente
Active el registro de depuración para tener una mejor idea de lo que está sucediendo.
Puede saber si las cookies de sesión se están configurando utilizando un depurador del lado del navegador para ver los encabezados devueltos en las respuestas HTTP. (También hay otras formas).
Una posibilidad es que SpringSecurity esté configurando cookies de sesión segura y la siguiente página solicitada tenga una URL "http" en lugar de una URL "https". (El navegador no enviará una cookie segura para una URL "http").
fuente
La nueva función de filtrado en Servlet 2.4 básicamente alivia la restricción de que los filtros solo pueden operar en el flujo de solicitudes antes y después del procesamiento real de solicitudes por parte del servidor de aplicaciones. En cambio, los filtros de Servlet 2.4 ahora pueden interactuar con el despachador de solicitudes en cada punto de envío. Esto significa que cuando un recurso web reenvía una solicitud a otro recurso (por ejemplo, un servlet que envía la solicitud a una página JSP en la misma aplicación), un filtro puede estar funcionando antes de que el recurso de destino maneje la solicitud. También significa que si un recurso web incluye la salida o función de otros recursos web (por ejemplo, una página JSP que incluye la salida de varias otras páginas JSP), los filtros de Servlet 2.4 pueden funcionar antes y después de cada uno de los recursos incluidos. .
Para activar esa función, necesita:
web.xml
Controlador de registro
fuente
Estaba tratando de probar una aplicación extjs y después de configurar con éxito un testingAuthenticationToken, esto de repente dejó de funcionar sin una causa obvia.
No pude hacer que las respuestas anteriores funcionaran, por lo que mi solución fue omitir este poco de primavera en el entorno de prueba. Introduje una costura alrededor de la primavera como esta:
El usuario es un tipo personalizado aquí.
Luego lo estoy envolviendo en una clase que solo tiene una opción para que el código de prueba cambie el resorte.
La versión de prueba se ve así:
En el código de llamada, sigo usando un usuario adecuado cargado desde la base de datos:
Obviamente, esto no será adecuado si realmente necesita usar la seguridad, pero estoy ejecutando una configuración sin seguridad para la implementación de prueba. Pensé que alguien más podría encontrarse con una situación similar. Este es un patrón que he usado antes para simular dependencias estáticas. La otra alternativa es que puede mantener la estática de la clase contenedora, pero yo prefiero esta, ya que las dependencias del código son más explícitas, ya que debe pasar CurrentUserAccessor a las clases donde sea necesario.
fuente