with mvc java spring spring-security wicket

java - mvc - spring security web



Uso programático de Spring Security (6)

Tal vez no sea una respuesta completa a sus preguntas, pero tal vez podría ayudarlo.

El código que se invoca cuando NO se utiliza el inicio de sesión programático, pero uno estándar se encuentra aquí:

org.springframework.security.ui.webapp.AuthenticationProcessingFilter

Supongo que estabas inspirado por esto en tu código. Se ve bastante similar.

De manera similar, el código ejecutado cuando accede al /j_spring_security_logout en el enfoque estándar, se encuentra aquí:

org.springframework.security.ui.logout.LogoutFilter

LogoutFilter llama a múltiples controladores. El controlador que estamos utilizando se llama: org.springframework.security.ui.logout.SecurityContextLogoutHandler , por lo que puede llamar al mismo código en su enfoque.

Estoy usando Wicket con el Wicket Auth Project para mi capa de presentación y, por lo tanto, lo he integrado con Spring Security. Este es el método que Wicket llama para la autenticación para mí:

@Override public boolean authenticate(String username, String password) { try { Authentication request = new UsernamePasswordAuthenticationToken( username, password); Authentication result = authenticationManager.authenticate(request); SecurityContextHolder.getContext().setAuthentication(result); } catch (AuthenticationException e) { return false; } return true; }

Los contenidos (adentro) de mi configuración de Spring Security XML son:

<http path-type="regex"> <form-login login-page="/signin"/> <logout logout-url="/logout" /> </http> <global-method-security secured-annotations="enabled" /> <authentication-manager alias="authenticationManager"/> <authentication-provider user-service-ref="userService"> <password-encoder ref="bcryptpasswordencoder" /> </authentication-provider>

La sección 2.3.6. La protección contra ataques de fijación de sesión de la documentación de referencia dice:

Los ataques de fijación de sesión son un riesgo potencial cuando un atacante malintencionado puede crear una sesión accediendo a un sitio y persuadir a otro para que inicie sesión con la misma sesión (enviándoles un enlace que contiene el identificador de sesión como parámetro, para ejemplo). Spring Security protege contra esto automáticamente creando una nueva sesión cuando un usuario inicia sesión. Si no requiere esta protección, o entra en conflicto con algún otro requisito, puede controlar el comportamiento utilizando el atributo session-fixation-protection en, que tiene tres opciones:

  • migrateSession: crea una nueva sesión y copia los atributos de sesión existentes en la nueva sesión. Este es el predeterminado.
  • ninguno - No hagas nada. La sesión original será retenida.
  • newSession - Crea una nueva sesión "limpia", sin copiar los datos de sesión existentes.

La autenticación funciona, pero como soy bastante nuevo en Spring Security, tengo algunas preguntas que también necesito respuestas:

  • Normalmente, para iniciar sesión, j_spring_security_check información de autenticación a j_spring_security_check y deje que Spring Security realice el código de autenticación real. Me gustaría tener protección contra los ataques de fijación de sesiones, ¿lo obtendré cuando realice un inicio de sesión programático como lo hago? Y si no, ¿qué tendría que hacer para obtenerlo?
  • ¿Cómo realizo el cierre de sesión programático?
  • Como usaré el inicio de sesión programático y el cierre de sesión, ¿cómo desactivo que Spring intercepte esas URL?

Actualización: para la protección de ataque de fijación de sesión parece que necesito llamar al método en la clase SessionUtils con la firma startNewSessionIfRequired(HttpServletRequest request, boolean migrateAttributes, SessionRegistry sessionRegistry) .

¿Cómo obtengo la instancia de SessionRegistry que necesito pasar? No puedo encontrar ninguna forma de crear una ID de alias, o cómo obtener su ID o nombre.


1) Cierre de sesión programático

  1. llame a HttpServletRequest.getSession (false) .invalidate
  2. llame a SecurityContextHolder.clearContext ()

2) Dile a Spring Security que NO intercepte ciertas URL, este tipo de depende de cómo se configura el espacio de la URL de la aplicación. Si todas sus páginas (excepto / logIn y / logout) vivieran en el contexto / myApp, podría hacer esto:

<http ....> <intercept-url pattern="/myApp/**" ..> .... </http>


Tuve un problema con el inicio de sesión programático. Llamé a todos los métodos authenticationManager.authenticate(...) y SecurityContextHolder.getContext().setAuthentication(...) pero tuve algunos problemas con la sesión. Tuve que agregar las siguientes líneas para administrar adecuadamente la sesión:

HttpSession session = request.getSession(); session.setAttribute("SPRING_SECURITY_CONTEXT", SecurityContextHolder.getContext());

Esto no estaba claro en el código de ejemplo publicado anteriormente. Para más información, consulte http://forum.springsource.org/showthread.php?t=69761


Para realizar el cierre de sesión programático también es posible lanzar una org.springframework.security.core.AuthenticationException . Por ejemplo, SessionAuthenticationException . En este caso, ExceptionTranslationFilter inicia el cierre de sesión.


Puedes intentar esto

try { HttpSession session = request.getSession(false); if (session != null) { session.invalidate(); } SecurityContextHolder.clearContext(); } catch (Exception e) { logger.log(LogLevel.INFO, "Problem logging out."); }


De hecho, estarás abierto a los ataques de fijación de sesiones. Para remediar esto, podría ser "inspirado" por el código de Spring. Para crear una nueva sesión, obviamente necesitará acceder a la httpsession, por lo que es posible que tenga que hacer algunas refactorizaciones.

Si ve el método SessionUtils . startNewSessionIfRequired .

Esto migrará la autenticación a una nueva sesión. Es posible que pueda llamar a este método directamente o simplemente refactorizar el código un poco.

En cuanto al cierre de sesión programático, no puede ir demasiado mal simplemente llamando a session.invalidate() cuando necesita desconectar a la persona. Esto hará todo lo necesario desde una perspectiva de seguridad general, pero tenga en cuenta que es posible que necesite limpiar algunas cosas en la sesión. Si tiene un conjunto de filtros muy complicado, etc. y necesita asegurarse de que el usuario se desconecta por el resto de la solicitud, puede agregar:

SecurityContextHolder.getContext().setAuthentication(null);

¡En cuanto a la interceptación de las URL, podrías simplemente ponerlas en algo sin usar e ignorarlas! No estoy seguro si puede desactivar la interceptación en la configuración; si realmente desea eliminarla, eche un vistazo al AuthenticationProcessingFilter , puede personalizar esto. Si hace esto, tendrá que configurar manualmente el xml de seguridad de primavera y no usar los espacios de nombres proporcionados. Sin embargo, no es demasiado difícil: mira algunos documentos anteriores y verás cómo hacerlo.

¡Espero que esto ayude!