-
-
Save banterCZ/5160269 to your computer and use it in GitHub Desktop.
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.security.web.session.InvalidSessionStrategy; | |
import org.springframework.util.StringUtils; | |
import javax.servlet.ServletException; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import java.io.IOException; | |
/** | |
* Inspired by <a href="http://stackoverflow.com/questions/10143539/jsf-2-spring-security-3-x-and-richfaces-4-redirect-to-login-page-on-session-tim">StackOverflow.com</a> | |
* and by <a href="http://www.icesoft.org/wiki/display/ICE/Spring+Security#SpringSecurity-Step4%3AConfigureYourSpringSecurityredirectStrategy">Spring Security 3 and ICEfaces 3 Tutorial</a>. | |
* | |
* @author banterCZ | |
*/ | |
public class JsfRedirectStrategy implements InvalidSessionStrategy { | |
private Logger logger = LoggerFactory.getLogger(getClass()); | |
private static final String FACES_REQUEST_HEADER = "faces-request"; | |
private String invalidSessionUrl; | |
/** | |
* {@inheritDoc} | |
*/ | |
@Override | |
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { | |
boolean ajaxRedirect = "partial/ajax".equals(request.getHeader(FACES_REQUEST_HEADER)); | |
if(ajaxRedirect) { | |
String contextPath = request.getContextPath(); | |
String redirectUrl = contextPath + invalidSessionUrl; | |
logger.debug("Session expired due to ajax request, redirecting to '{}'", redirectUrl); | |
String ajaxRedirectXml = createAjaxRedirectXml(redirectUrl); | |
logger.debug("Ajax partial response to redirect: {}", ajaxRedirectXml); | |
response.setContentType("text/xml"); | |
response.getWriter().write(ajaxRedirectXml); | |
} else { | |
String requestURI = getRequestUrl(request); | |
logger.debug("Session expired due to non-ajax request, starting a new session and redirect to requested url '{}'", requestURI); | |
request.getSession(true); | |
response.sendRedirect(requestURI); | |
} | |
} | |
private String getRequestUrl(HttpServletRequest request) { | |
StringBuffer requestURL = request.getRequestURL(); | |
String queryString = request.getQueryString(); | |
if (StringUtils.hasText(queryString)) { | |
requestURL.append("?").append(queryString); | |
} | |
return requestURL.toString(); | |
} | |
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(); | |
} | |
public void setInvalidSessionUrl(String invalidSessionUrl) { | |
this.invalidSessionUrl = invalidSessionUrl; | |
} | |
} |
<beans xmlns="http://www.springframework.org/schema/beans" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xmlns:sec="http://www.springframework.org/schema/security" | |
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd | |
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> | |
<sec:http pattern="/pages/public/**" security="none"/> | |
<sec:http pattern="/javax.faces.resource/**" security="none"/> | |
<sec:http use-expressions="true" > | |
<sec:custom-filter ref="sessionManagementFilter" before="SESSION_MANAGEMENT_FILTER" /> | |
<sec:intercept-url pattern="/pages/protected/**" access="isAuthenticated()" /> | |
<sec:form-login login-page='/pages/public/login.xhtml' default-target-url="/pages/protected/index.xhtml" | |
authentication-failure-url="/pages/public/login.xhtml?failure=true" /> | |
<sec:logout logout-success-url="/pages/public/login.xhtml"/> | |
</sec:http> | |
<sec:authentication-manager> | |
<sec:authentication-provider> | |
<sec:user-service> | |
<sec:user name="joe" password="password" authorities="ROLE_USER"/> | |
</sec:user-service> | |
</sec:authentication-provider> | |
</sec:authentication-manager> | |
<bean id="sessionManagementFilter" class="org.springframework.security.web.session.SessionManagementFilter"> | |
<constructor-arg name="securityContextRepository" ref="httpSessionSecurityContextRepository" /> | |
<property name="invalidSessionStrategy" ref="jsfRedirectStrategy" /> | |
</bean> | |
<bean id="jsfRedirectStrategy" class="JsfRedirectStrategy"> | |
<property name="invalidSessionUrl" value="/pages/public/error/viewExpired.xhtml" /> | |
</bean> | |
<bean id="httpSessionSecurityContextRepository" class="org.springframework.security.web.context.HttpSessionSecurityContextRepository"/> | |
</beans> |
<ui:composition template="/WEB-INF/templates/public_layout.xhtml" | |
xmlns="http://www.w3.org/1999/xhtml" | |
xmlns:h="http://java.sun.com/jsf/html" | |
xmlns:ui="http://java.sun.com/jsf/facelets" | |
> | |
<ui:param name="title" value="#{msg['error.viewExpired.title']}" /> | |
<ui:define name="content"> | |
#{msg['error.viewExpired.text']} | |
<h:outputLink value="#{header['referer']}">#{msg['link.back']}</h:outputLink> | |
</ui:define> | |
</ui:composition> |
<?xml version="1.0" encoding="UTF-8"?> | |
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" | |
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> | |
<servlet> | |
<servlet-name>Faces Servlet</servlet-name> | |
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class> | |
<load-on-startup>1</load-on-startup> | |
</servlet> | |
<context-param> | |
<param-name>contextConfigLocation</param-name> | |
<param-value> | |
classpath:security.xml | |
</param-value> | |
</context-param> | |
<listener> | |
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> | |
</listener> | |
<listener> | |
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class> | |
</listener> | |
<servlet-mapping> | |
<servlet-name>Faces Servlet</servlet-name> | |
<url-pattern>*.xhtml</url-pattern> | |
</servlet-mapping> | |
<filter> | |
<filter-name>springSecurityFilterChain</filter-name> | |
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> | |
</filter> | |
<filter-mapping> | |
<filter-name>springSecurityFilterChain</filter-name> | |
<url-pattern>/*</url-pattern> | |
</filter-mapping> | |
</web-app> |
Thank a lot man!
Thank, you bro!
It helps me a lot. With your solution, i could turn my javascript's integrations more rich. I only add "response.setStatus(int n)" in onInvalidSessionDetected file to facilitate in jQuery.post.
:)
You saved my life ;)
Great work, however, you shouldn't put the RedirectStrategy code inside your implementation of "InvalidSessionStrategy", however you should delegate the work to an implementation of RedirectStrategy instead. (exactly as SimpleRedirectInvalidSessionStrategy works.)
Great work, however, I added in the file of config
and in the face-config
< lifecycle>
web.util.CacheControlPhaseListener< /phase-listener>
< / lifecycle>
public class CacheControlPhaseListener implements PhaseListener {
private static final long serialVersionUID = 2475683599960651934L;
@OverRide
public void afterPhase(PhaseEvent event) {}
@Override
public void beforePhase(PhaseEvent event) {
FacesContext facesContext = event.getFacesContext();
HttpServletResponse response = (HttpServletResponse) facesContext
.getExternalContext().getResponse();
response.addHeader("Pragma", "no-cache");
response.addHeader("Cache-Control", "no-cache");
// Stronger according to blog comment below that references HTTP spec
response.addHeader("Cache-Control", "no-store");
response.addHeader("Cache-Control", "must-revalidate");
// some date in the past
response.addHeader("Expires", "Thu, 01 Dec 1994 16:00:00 GMT");
}
@Override
public PhaseId getPhaseId() {
return PhaseId.RENDER_RESPONSE;
}
}
otherwise many problems appear.
what do you think ?
Worked like a charm, thank you!
Thanks!!!
thank you very much for solution :)