java - dinamico - Spring-Security: método de llamada después de la autenticación
spring security authorities (7)
En caso de que desee continuar con el comportamiento predeterminado pero solo entre realizar su propia lógica empresarial, puede extend SimpleUrlAuthenticationSuccessHandler
e invocar super.onAuthenticationSuccess(request, response, authentication);
antes de regresar Más detalles consulte https://stackoverflow.com/a/6770785/418439
Me gustaría hacer un seguimiento cuando los usuarios están iniciando sesión en mi aplicación. Tengo un código que me gustaría ejecutar justo después de autenticar al usuario. El problema es que no puedo averiguar de dónde debería llamarse. ¿Spring-security tiene una forma de llamar a un método después de la autenticación?
Este enlace La lógica de autenticación posterior en ByteClip explica cómo ejecutar cierta lógica después de la autenticación exitosa sin molestar la cadena de filtros de seguridad de resorte
La autenticación no implica necesariamente un inicio de sesión exitoso. Un usuario puede autenticarse con éxito a través de, por ejemplo, SSL de dos vías (certificados X.509), y aún así Spring Security lo redireccionará a una página de error si la administración de concurrencia de sesión está configurada con max-sessions="1"
y esto es un segundo intento de inicio de sesión concurrente. Si su configuración es simple, sin control de concurrencia de sesión, puede asumir login = autenticación para todos los propósitos prácticos. De lo contrario, si tiene, por ejemplo, una lógica que registra cada inicio de sesión exitoso en una base de datos, tendrá que invocar esta lógica en el punto de inicio de sesión real , no en el punto de autenticación. Una manera (de ninguna manera óptima, sujeta a mi comprensión limitada del marco de Spring Security) para hacer esto es implementar su propia ConcurrentSessionControlAuthenticationStrategy
(haga clic here para obtener el código fuente) e inyectarlo en CompositeSessionAuthenticationStrategy
en su Spring Security (3.2 y superior) configuración XML:
<http>
.
.
<session-management session-authentication-strategy-ref="sas" />
.
.
</http>
.
.
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.CompositeSessionAuthenticationStrategy">
<beans:constructor-arg>
<beans:list>
<beans:bean class="path.to.my.implementation.of.ConcurrentSessionControlAuthenticationStrategy">
<beans:constructor-arg ref="sessionRegistry"/>
<beans:property name="maximumSessions" value="1"/>
<beans:property name="exceptionIfMaximumExceeded" value="true"/>
<beans:bean>
<beans:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"/>
<beans:bean class="org.springframework.security.web.authentication.session.RegisterSessionAuthenticationStrategy"/>
<beans:constructor-arg ref="sessionRegistry"/>
</beans:bean>
</beans:list>
</beans:constructor-arg>
</beans:bean>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
Hubiera preferido inyectar un controlador PostLogin
personalizado en la PostLogin
ConcurrentSessionControlAuthenticationStrategy
, en lugar de copiar y pegar desde él en mi estrategia ConcurrentSessionControlAuthenticationStrategy
y hacer modificaciones, pero no sé cómo hacerlo en este momento.
Un ejemplo de configuración más completa se puede encontrar here .
La mejor manera es crear un escucha de aplicación y registrarlo con el contexto de seguridad de Spring.
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
public class AuthenticationSuccessListener implements ApplicationListener<InteractiveAuthenticationSuccessEvent> {
@Override
public void onApplicationEvent(InteractiveAuthenticationSuccessEvent event) {
System.out.println("User Logged In");
}
}
Asegúrese de agregar la clase anterior el spring-security.xml como un bean. Hay muchos otros tipos de escuchas de eventos de seguridad que puede escuchar, verifique la jerarquía de tipos para obtener una lista de todos los tipos de eventos de seguridad que puede escuchar.
Probablemente será útil para alguien ... En el caso de Spring 3, configure la seguridad:
<security:http use-expressions="true" auto-config="true">
<security:intercept-url pattern="..."/>
<security:form-login
authentication-failure-handler-ref="authFailureHandler"
authentication-success-handler-ref="authSuccessHandler"/>
<security:logout success-handler-ref="logoutSuccessHandler"
invalidate-session="true"/>
<security:session-management session-fixation-protection="newSession"/>
</security:http>
<bean id="authFailureHandler" class="mine.AuthenticationFailureHandlerImpl"/>
<bean id="authSuccessHandler" class="mine.AuthenticationSuccessHandlerImpl"/>
<bean id="logoutSuccessHandler" class="mine.LogoutSuccessHandlerImpl"/>
e implementar una clase apropiada:
public class AuthenticationSuccessHandlerImpl implements AuthenticationSuccessHandler {
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
//do what you want with
response.getOutputStream().write("success".getBytes());
}
}
Puedes vincular recursos a través de esa configuración xml.
Si desea evitar leer todo el hilo: versión curada con anotaciones y un poco más explicativo:
import org.springframework.context.ApplicationListener;
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;
@Component
public class LoginSuccessListener implements ApplicationListener<AuthenticationSuccessEvent{
@Override
public void onApplicationEvent(AuthenticationSuccessEvent evt) {
// if you just need the login
String login = evt.getAuthentication().getName();
System.out.println(login + " has just logged in");
// if you need to access full user (ie only roles are interesting -- the rest is already verified as login is successful)
User user = (User) evt.getAuthentication().getPrincipal();
System.out.println(user.getUsername() + " has just logged in");
}
}
Simplemente escriba su propio SpringSecurityFilter y agréguelo a la cadena de filtros justo después de llamar a su proveedor de autenticación.
package my.code;
public class AuditFilter extends SpringSecurityFilter {
public void doFilterHttp(...) throws ... {
{application code to run before request is processed}
chain.doFilter(...);
{application code to run after request has fully processed}
}
}
Luego, en su configuración XML (donde sea que configure la cadena del Filtro de Seguridad) agregue una línea como esta:
<bean id="auditFilter" class="my.code.AuditFilter>
<security:custom-filter position="LAST"/> <-- you can change the position
</bean>