jueves, 2 de marzo de 2017

Spring Security: Redirección tras login

En un post anterior ya hemos explicado como realizar el login con usuario/contraseña y con redes sociales. Pero en ese ejemplo siempre volvíamos a una página fija y eso no siempre le da la mejor experiencia al usuario. Por eso en este post vamos a tratar como realizar la redirección tras intentar logarse tanto si va bien, como si no. 

El primer paso es modificar la configuración de Spring Security para indicarle que serán clases nuestras las que se encargen de la redirección

@Bean
public SavedRequestAwareAuthenticationSuccessHandler successHandler() {
   SavedRequestAwareAuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
   successHandler.setUseReferer( true );
   return successHandler;
}
@Bean
public SimpleUrlAuthenticationFailureHandler failureHandler() {
   return new CustomAuthenticationFailureHandler();
}
@Override
protected void configure( final HttpSecurity http ) throws Exception {
// @formatter:off
// configures form login
http.formLogin().loginPage( "/login").permitAll().successHandler( successHandler() ).failureHandler( failureHandler() )
// more configuration
...
// @formatter:on
}

Para el caso del login, si lo único que queremos hacer es que redirija a la página hacia la cual se redirigía el usuario al saltar el login, tendremos que poner la propiedad 'UseReferer' a 'true'. Si queremos alguna acción más, deberemos crear una clase que implemente 'SavedRequestAwareAuthenticationSuccessHandler'. Ejemplo:

@Component
public class CustomAuthenticationSuccessHandler extends SavedRequestAwareAuthenticationSuccessHandler {
 @Override
 public void onAuthenticationSuccess( final HttpServletRequest request, final HttpServletResponse response, final Authentication authentication ) throws IOException, ServletException {
  CustomUserDetails user = (com.example.app.CustomUserDetails) authentication.getPrincipal();
  request.getSession().setAttribute( SESSION.USER_LANGUAGE_ID, user.getLanguageId() );
  super.onAuthenticationSuccess( request, response, authentication );
 }
}

Para el caso de logout es muy similar, pero la redirección no podremos hacerla automática sino que tendremos que implementar una clase de la API de Spring que realice dicha lógica. En nuestro ejemplo le añadiremos la coletilla de que ha ocurrido error durante el login, para que lo muestre en la pantalla desde la cual ha intentado logarse.


@Component
public class CustomAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {
 @Override
 public void onAuthenticationFailure( final HttpServletRequest request, final HttpServletResponse response, final AuthenticationException exception ) throws IOException, ServletException {
  String referer =  request.getHeader( "referer" );
  String redirectUrl = StringUtils.substringBeforeLast( referer, "?" ) + "?login_error=1";
  redirectUrl = response.encodeRedirectURL( redirectUrl );
  response.sendRedirect( redirectUrl );
 }
}

No hay comentarios:

Publicar un comentario