JSF 2,Spring Security 3.x和Richfaces 4在会话超时时重定向到登录页面以获取ajax请求

时间:2012-04-13 15:14:36

标签: spring jsf-2 spring-security

这似乎是一个非常普遍的问题。但我找不到任何可行的解决方案。我们使用的是Richafaces 4,Myfaces 2.0.5和Spring security 3.0.X。

在ajax / non ajax请求的会话时间内,应该将用户重定向到登录页面。在记录回来之后,应该显示先前执行的ajax / non ajax操作。

我们没有遇到任何非Ajax请求的问题。但是对于ajax请求,用户不会被重定向到登录页面。

我已关注此链接https://community.jboss.org/message/729913#729913并实施了servlet方法。该解决方案适用于Firefox,而不是IE 8。

即使在会话超时时正确地重定向到登录页面,也可能存在一个问题。我希望在成功登录以前调用的ajax请求时出现ViewExpiredException。

我想引入ViewExpiredException,因为这两个问题可能相互关联。

任何解决方案/线索都将受到赞赏。

2 个答案:

答案 0 :(得分:6)

由于您使用的是Spring Security 3.0.x,因此您可以按照here所述使用自定义sessionManagementFilter

com.icesoft.spring.security.JsfRedirectStrategy课程可用here

如果您正在使用Spring Security 3.1.x进行这些更改

 <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"/>

对JSFRedirectStrategy类的唯一更改是前几行:

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);

这也适用于IE8。如果你有兴趣,你也可以看一下blog,但我从未尝试过这个,因为上面的内容要容易得多。

仅供参考:如果你不做Spring,有很多方法可以做到这一点: Primefaces在他们的网站上做这件事。 link 甚至可以通过导入Omnifaces jar link

来简化

答案 1 :(得分:0)

我将Ravi的回答与How to set a custom invalid session strategy in Spring Security合并。

修改过滤器而不是创建新过滤器。 如果你也愿意,可以分成多个班级。

    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>