Spring Security sesson timeout not recognized on ajax call
I want to redirect users to the login page when a session timeout occurs. This works out-of-the-box with spring security, but only on non-ajax calls.
On an ajax-call you have to react on the session timeout by yourself. Therefore I have created
my own filter(filter implemented like in this question) who checks if a session is timed out. The filter is registered via custom-filter
tag in spring security config.
<http use-expressions="true">
<custom-filter ref="customTimeoutHandler" after="LAST"/>
</http>
The problem is, that the session timeout is not recognized by the filter. If I check for request.isRequestedSessionIdValid()
it returns true
even if the session is timed out. When I enter a new secured URL manually, the standard spring security filter recognizes the timeout correctly and does a redirect to the login page.
What could be wrong here? How recognizes spring security the session timeout?
UPDATE
It seems, that the session management filter of spring security re开发者_开发问答places the timed-out session with a new anonymous one. Therefore everytime I check for session timeout it returns true
, because the new anonymous session is, of course, not timed-out.
You can check the SecurityContext
.
Grab the Authentication
object and check the authorities looking for an ANONYMOUS
one. Something like:
SecurityContext sc = SecurityContextHolder.getContext();
Authentication a = sc.getAuthentication();
if(!a.isAuthenticated() || a.getAuthorities().contains(new GrantedAuthorityImpl("ROLE_ANONYMOUS"))) {
//user not authenticated or ANONYMOUS
} else {
//user authenticated
}
This solution works like a charm for me.
The basic concept is to point to a servlet instead of the login page. The servlet then determines if the request was a ajax request and if that is true, it returns the redirect to the login page as xml fragment. The browser can interpret that fragment and redirects to the login page.
I am developing enterprise application including gwt/gwtp and spring security . I add some issue with session time out , casue the SimpleRedirectInvalidSessionStrategy which used by default is executing response.sendRedirect() , the html page response I wanted to redirect is swallow by gwt com.google.gwt.user.client.rpc.InvocationException as the exception message . and no actully redirect is taking place .
for solving this
1 . I define my cosutom session-manamgemt-filter
for doing this you need in your spring-security.xml configuration file set
<session-management session-fixation-protection="none"/>
by this spring secuirty will not take it default session managment filter .
define your session managment filter
enter code here
{
<custom-filter position="SESSION_MANAGEMENT_FILTER" ref="mySessionManagmentFilter"/>
<beans:bean id="mySessionManagmentFilter"
class="org.springframework.security.web.session.SessionManagementFilter">
<beans:constructor-arg index="0" ref="mySessionSecurityContextRepository"/>
<beans:constructor-arg index="1" ref="mySessionAutenticationStrategy"/>
<beans:property name="invalidSessionStrategy">
<beans:ref local="myInvalidSessionStrategy"/>
</beans:property>
</beans:bean>
<beans:bean id="mySessionSecurityContextRepository"
class='org.springframework.security.web.context.HttpSessionSecurityContextRepository'>
<beans:property name='allowSessionCreation' value='false'/>
</beans:bean>
<beans:bean id="mySessionAutenticationStrategy"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry"/>
<beans:property name="maximumSessions" value="1"/>
<beans:property name="exceptionIfMaximumExceeded" value="false"/>
<beans:property name="alwaysCreateSession" value="true"/>
</beans:bean>
<beans:bean id="myInvalidSessionStrategy"
class="com.my.project.MyInvalidSessionStrategy">
<beans:constructor-arg value="/login.jsp?timeout=1"/>
</beans:bean>
}
here custom - MyInvalidSessionStrategy {
public class MyInvalidSessionStrategy implements InvalidSessionStrategy {
private final Logger logger = LoggerFactory.getLogger(getClass());
private final String destinationUrl;
public OperationalInvalidSessionStrategy(String invalidSessionUrl) {
this.destinationUrl = invalidSessionUrl;
}
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
String exMsg =session timeout ! , need to redirect to login page
logger.warn(exMsg);
throw new TimeOutException(exMsg);
}
}
}
so when time out taking place the new implementation is throwing an exception .. the exception can be truck on gwt callback onFailure method
check the type of the exception and on onFailure method redirect the user to login page .
with Window.Location.replace(GWT.getHostPageBaseURL() + "/login.jsp")
精彩评论