JSF 2, Spring Security 3.x and Richfaces 4 redirect to login page on session time out for ajax requests

前端 未结 2 1953
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-05 22:05

It seems a very common problem. But I couldn\'t find any working solution. We are using Richafaces 4, Myfaces 2.0.5 and Spring security 3.0.X.

On session time for aj

相关标签:
2条回答
  • 2020-12-05 22:27

    Since you use Spring Security 3.0.x, you can use custom sessionManagementFilter as described here

    The class com.icesoft.spring.security.JsfRedirectStrategy is available here

    If you are using Spring Security 3.1.x make these changes

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

    The only change to the JSFRedirectStrategy class are the first few lines:

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

    This works with IE8 also. If you are interested you can look at this blog also, but I never tried this as the above was much easier.

    FYI: If you do not do Spring there are many ways to do this: Primefaces does this on their site. link Or even simpler by importing Omnifaces jar link

    0 讨论(0)
  • 2020-12-05 22:29

    I merge Ravi's answer with How to set a custom invalid session strategy in Spring Security.

    It modify the filter instead of creating a new one. Can split in multiple class if you want too.

        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>
    
    0 讨论(0)
提交回复
热议问题