2012-04-13 10 views
5

Parece un problema muy común. Pero no pude encontrar ninguna solución funcional. Estamos utilizando Richafaces 4, Myfaces 2.0.5 y Spring security 3.0.X.JSF 2, Spring Security 3.xy Richfaces 4 redireccionan a la página de inicio de sesión en el tiempo de espera de la sesión para las solicitudes ajax

En el tiempo de sesión para las solicitudes ajax/no ajax, el usuario debe ser redirigido a la página de inicio de sesión. Después de volver a iniciar sesión, se le debe mostrar la operación realizada anteriormente ajax/no ajax.

No estamos enfrentando ningún problema con las solicitudes no AJAX. Pero para las solicitudes ajax, el usuario no se redirige a la página de inicio de sesión.

He seguido este enlace https://community.jboss.org/message/729913#729913 y he implementado el enfoque servlet. la solución funcionó en Firefox, no en IE 8.

Podría haber un problema más, incluso si se redirige correctamente a la página de inicio de sesión en el tiempo de espera de la sesión. Estoy esperando una ViewExpiredException en el inicio de sesión exitoso para la solicitud ajax invocada anteriormente.

Quería traer ViewExpiredException, ya que ambos problemas podrían relacionarse entre sí.

Se agradecerán todas las soluciones/clientes potenciales.

+0

sesión personalizada La estrategia de gestión de gestión y jsfredirect solucionó el problema de tiempo de espera de la aplicación en solicitudes ajax. Nos enfrentamos a otro problema en el tiempo de espera de la sesión de SSO. SSO se está utilizando en nuestra empresa, el ID de usuario se pasa en el encabezado de solicitud a la aplicación. Supongamos que se ha agotado el tiempo de espera de la sesión de SSO, la sesión de la aplicación aún está activa. Ahora, si el usuario realiza una solicitud de AJA, el SSO interferirá e intentará redirigir a la página de inicio de sesión de SSO. Ajax no puede analizar sso repsone y se vuelve irresponsable en la página. Cualquier solución/cliente potencial será apreciada. Gracias Ravi –

Respuesta

6

Puesto que se utiliza 3.0.x Spring Security, puede utilizar a medida sessionManagementFilter como se describe here

La clase com.icesoft.spring.security.JsfRedirectStrategy está disponible here

Si está usando Spring Security 3.1 .X hacer estos cambios

<beans:bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter"> 
    <beans:constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" /> 
      <!-- this permits redirection to session timeout page from javascript/ajax or http --> 
    <beans:property name="invalidSessionStrategy" ref="jsfRedirectStrategy" /> 
</beans:bean> 

<beans:bean id="jsfRedirectStrategy" class="com.icesoft.spring.security.JsfRedirectStrategy"> 
    <beans:constructor-arg name="invalidSessionUrl" value="/general/logins/sessionExpired.jsf" /> 
</beans:bean> 
<beans:bean id="httpSessionSecurityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/> 

el único cambio en la clase JSFRedirectStrategy son las primeras líneas:

public class JsfRedirectStrategy implements InvalidSessionStrategy { 
protected final Log logger = LogFactory.getLog(getClass()); 
    private String invalidSessionUrl; 
private boolean contextRelative; 

public JsfRedirectStrategy(String invalidSessionUrl){ 
    this.invalidSessionUrl=invalidSessionUrl; 
} 

@Override 
public void onInvalidSessionDetected(HttpServletRequest request, 
     HttpServletResponse response) throws IOException, ServletException { 
    String redirectUrl = calculateRedirectUrl(request.getContextPath(), invalidSessionUrl); 

Esto también funciona con IE8. Si está interesado puede consultar este blog también, pero nunca lo intenté ya que lo anterior fue mucho más fácil.

FYI: Si no hace Spring, hay muchas formas de hacerlo: Primefaces lo hace en su sitio. link O aún más simple mediante la importación de Omnifaces frasco link

+0

Hola Ravi, gracias por la solución. Me funcionó. He realizado algunos cambios en la estrategia de redirección.guardando el requerimiento actual en el caché de solicitudes para solicitudes que no son Ajax, de modo que el usuario será redirigido a una solicitud previa cuando se conectó, sin embargo, no estamos almacenando las solicitudes ajax en el caché de solicitudes antes de redireccionar. el usuario será redirigido a la página de inicio predeterminada después de la sesión iniciada. si las solicitudes ajax se almacenan en el caché de solicitudes, entonces verá la excepción caducada. Idealmente, queremos que se realice la solicitud ajax anterior cuando el usuario vuelve a iniciar sesión después del tiempo de espera de la sesión. Gracias Ravi J –

+0

Hemos cambiado al cliente STATE_SAVING_METHOD ya que la nuestra es una aplicación de intranet, por lo que no obtenemos ninguna excepción expirada. Pero de todos modos estoy contento de que te haya ayudado. Marque la respuesta aceptada si le ha funcionado ... – Ravi

+0

@Ravi Gracias por la inspiración, aquí hay [mi implementación de JsfRedirectStrategy] (https://gist.github.com/banterCZ/5160269) – banterCZ

0

combino la respuesta de Ravi con How to set a custom invalid session strategy in Spring Security.

Modifica el filtro en lugar de crear uno nuevo. Puede dividirse en varias clases si lo desea también.

public class JSFRedirectStrategy implements InvalidSessionStrategy, 
    BeanPostProcessor { 

/** 
* JSF header 
*/ 
private static final String FACES_REQUEST_HEADER = "faces-request"; 

/** 
* URL 
*/ 
private String invalidSessionUrl; 

public void setInvalidSessionUrl(String invalidSessionUrl) { 
    this.invalidSessionUrl = invalidSessionUrl; 
} 

/** 
* {@inheritDoc} 
*/ 
@Override 
public void onInvalidSessionDetected(HttpServletRequest request, 
     HttpServletResponse response) throws IOException, ServletException { 
    String ajaxRedirectXml; 
    String requestURI; 

    // Force nouvelle session 
    request.getSession(true); 

    if ("partial/ajax".equals(request.getHeader(FACES_REQUEST_HEADER))) { 
     requestURI = request.getContextPath() + invalidSessionUrl; 
     requestURI = response.encodeRedirectURL(requestURI); 
     ajaxRedirectXml = createAjaxRedirectXml(requestURI); 
     response.setContentType("text/xml"); 
     response.getWriter().write(ajaxRedirectXml); 
    } else { 
     response.sendRedirect(response 
       .encodeRedirectURL(getRequestUrl(request))); 
    } 
} 

/** 
* Obtenir la requete qu'il voulait appeler 
* 
* @param request 
* @return 
*/ 
private String getRequestUrl(HttpServletRequest request) { 
    StringBuffer requestURL; 
    String queryString; 

    requestURL = request.getRequestURL(); 
    queryString = request.getQueryString(); 
    if (!JavaUtil.isNullOrEmpty(queryString)) 
     requestURL.append("?").append(queryString); 
    return requestURL.toString(); 
} 

/** 
* XML redirect 
* 
* @param redirectUrl 
* @return 
*/ 
private String createAjaxRedirectXml(String redirectUrl) { 
    return new StringBuilder() 
      .append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>") 
      .append("<partial-response><redirect url=\"") 
      .append(redirectUrl) 
      .append("\"></redirect></partial-response>").toString(); 
} 

@Override 
public Object postProcessBeforeInitialization(Object bean, String beanName) 
     throws BeansException { 
    SessionManagementFilter filter; 
    if (bean instanceof SessionManagementFilter) { 
     filter = (SessionManagementFilter) bean; 
     filter.setInvalidSessionStrategy(this); 
    } 
    return bean; 
} 

@Override 
public Object postProcessAfterInitialization(Object bean, String beanName) 
     throws BeansException { 
    return bean; 
}} 
    <!-- Afin de gerer l'ajax lorsque spring redirige vers la page auth --> 
<bean id="jsfRedirectStrategy" class="JSFRedirectStrategy" > 
    <property name="invalidSessionUrl" value="/authentification.qc" /> 
</bean> 
Cuestiones relacionadas