Reputation: 963
So user login -> closes the browser -> opens browser one more time -> error appears:
HTTP Status 401 - Authentication Failed: Maximum sessions of 1 for this principal exceeded
What I need is to capture this event that session is invalid, remove all sessions for this user and redirect to normal login page
spring security config:
<http auto-config="true" use-expressions="true">
<session-management session-fixation-protection="migrateSession">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="true"/>
</session-management>
<intercept-url pattern="/login" access="hasRole('ROLE_ANONYMOUS')" requires-channel="any"/>
<!--<custom-filter after="CONCURRENT_SESSION_FILTER" ref="sessionExpiration" /> -->
<!-- .... -->
</http>
<beans:bean id="sessionExpiration" class="com.test.security.SessionExpirationFilter">
<beans:property name="expiredUrl">
<beans:value>/login</beans:value>
</beans:property>
</beans:bean>
I tried to implement some filter, but it always shows that session is null:
public class SessionExpirationFilter implements Filter, InitializingBean {
private String expiredUrl;
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String path = httpRequest.getServletPath();
HttpSession session = httpRequest.getSession(false);
System.out.println(session);
if (session == null && !httpRequest.isRequestedSessionIdValid()) {
SecurityContextHolder.getContext().setAuthentication(null);
String targetUrl = httpRequest.getContextPath()
+ expiredUrl;
httpResponse.sendRedirect(httpResponse.encodeRedirectURL(targetUrl));
return;
}
chain.doFilter(request, response);
}
public void setExpiredUrl(String expiredUrl) {
this.expiredUrl = expiredUrl;
}
}
Upvotes: 1
Views: 7840
Reputation: 511
Based on the answers above
Spring security automatically invalidates previous session
if you want to redirect the user on login page, you can add
<session-management invalid-session-url="/login.html">
...
</session-management>
Since the previous session is already invalidated.
I have also read in your comment above that you may want to retain the previous session when you try to login again. This defeats your first question, but anyways.
are you talking about 7. Session Fixation Protection with Spring Security
The framework offers protection against typical Session Fixation attacks by configuring what happens to an existing session when the user tries to authenticate again:
<session-management session-fixation-protection="migrateSession">
The corresponding Java configuration:
http.sessionManagement().sessionFixation().migrateSession()
By default, Spring Security has this protection enabled (“migrateSession“) – on authentication a new HTTP Session is created, the old one is invalidated and the attributes from the old session are copied over.
If this is not the desired behavior, two other options are available:
when
“none”
is set, the original session will not be invalidatedwhen
“newSession”
is set, a clean session will be created without any of the attributes from the old session being copied over
Upvotes: 0
Reputation: 1
<session-management session-authentication-strategy-ref="sas"/>
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:property name="maximumSessions" value="1"/>
<beans:property name="exceptionIfMaximumExceeded" value="true"/>
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry"/>
</beans:bean>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl"/>
Upvotes: -1
Reputation: 5118
Setting error-if-maximum-exceeded="false"
will allow the second session and invalidate the first one as your max-sessions="1"
If you have max-sessions="2"
then it will allow the Nth
session also and invalidate all N-2
sessions
<session-management session-fixation-protection="migrateSession">
<concurrency-control max-sessions="1" error-if-maximum-exceeded="false"/>
</session-management>
Setting error-if-maximum-exceeded="true"
will NOT
allow the second session and invalidate the second session as your max-sessions="1"
If you have max-sessions="2"
then it will not allow the 2+
sessions and invalidate.
Upvotes: 2
Reputation: 5258
From what I understood, you want to invalidate the previous session if it User's session exceeds 'max-sessions'. Set the property 'error-if-maximum-exceeded' to false. Spring security automatically invalidates previous session.
If you are trying to do something different,
.
Upvotes: 6