JSF Session timeout and auto redirect to login page without user intraction eventhough Ajax push is active

StackOverflow https://stackoverflow.com/questions/19450158

I'm using Iceface Icepush in my JSF application to send some notifications to client. Because of this session timeout never happen on my application.

I've specified session timeout 15 mins. My requirement is, server should invalidate session if there is no actual client interaction for 15 mins.

I did some search in iceface forum and added this context param in web.xml

<context-param>
    <param-name>org.icefaces.strictSessionTimeout</param-name>
    <param-value>true</param-value>
</context-param>

also someone has specified to use sessionTimeoutMonitor in faces-config.xml

<application>
 <resource-handler>org.icefaces.impl.application.SessionTimeoutMonitor</resource-handler>
</application>

But nothing works.

有帮助吗?

解决方案 2

I wrote my own timeout monitor by extending the org.icefaces.impl.application.SessionTimeoutMonitor class and this works fine.

public class RWSessionTimeoutMonitor extends  SessionTimeoutMonitor{

private static Logger log = LoggerFactory.getLogger(RWSessionTimeoutMonitor.class);

public RWSessionTimeoutMonitor(ResourceHandler handler) {
    super(handler);
}

@Override
public boolean isResourceRequest(FacesContext context) {
    final ExternalContext externalContext = context.getExternalContext();
    //create session if non-ajax request
    final Object session = externalContext.getSession(!context.getPartialViewContext().isAjaxRequest());
    //if session invalid or expired block other resource handlers from running
    if (session == null) {
        //return false to force JSF to run and throw ViewExpiredException which eventually will be captured
        //and re-cast in a SessionExpiredException
        return false;
    }

    if (!EnvUtils.isStrictSessionTimeout(context)) {
        return getWrapped().isResourceRequest(context);
    }
    Map sessionMap = externalContext.getSessionMap();
    Long lastAccessTime = (Long) sessionMap.get(SessionTimeoutMonitor.class.getName());
    boolean isPushRelatedRequest = EnvUtils.isPushRequest(context);
    if (lastAccessTime == null || !isPushRelatedRequest) {
        lastAccessTime = System.currentTimeMillis();
        sessionMap.put(SessionTimeoutMonitor.class.getName(), System.currentTimeMillis());
    }

    int maxInactiveInterval;

    maxInactiveInterval = ((javax.servlet.http.HttpSession) session).getMaxInactiveInterval();

    if (System.currentTimeMillis() - lastAccessTime > maxInactiveInterval * 1000) {
        sessionMap.remove(SessionTimeoutMonitor.class.getName());
        externalContext.invalidateSession();
        log.info("No user request b/w max interval [{}], session is invalidated." , maxInactiveInterval );
    }

    return super.isResourceRequest(context);
}

}

其他提示

You can simply add to your main template, which is inherited by others secured *.xhtml files (perhaps works ONLY with PrimeFaces):

<p:idleMonitor timeout="600000">
    <p:ajax event="idle" listener="#{loggedBean.logOut()}" update="messagesIdle" />
 Or <p:ajax event="active" listener="#{messagesBean.showMessageInfo('Czy ta kawka nie była zbyt gorąca? :)')}" update="messagesIdle" />
</p:idleMonitor>

One hint - you can use only one idleMonitor per page!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top