How to Detect session expired or session timeout using spring3.
The key is this:
<beans:bean id="concurrencyFilter"
class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/session-expired.htm" />
</beans:bean>
expiredUrl points to the page to display when a session has expired. Read the full solution in the spec :
http://static.springsource.org/spring-security/site/docs/3.0.x/reference/session-mgmt.html#concurrent-sessions
Related
I am building an online Examination project with spring mvc and Hibernate as Frameworks and it is almost done, Now I am getting the problem with session
xml configuration of the session
<beans:bean id="hibernate4AnnotatedSessionFactory"
class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="annotatedClasses">
<beans:list>
<beans:value>com.app.spring.model.Result</beans:value>
</beans:list>
</beans:property>
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect
</beans:prop>
<beans:prop key="hibernate.show_sql">true</beans:prop>
<beans:prop key="hibernate.hbm2ddl.auto">true</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<!-- Inject the transaction manager -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<beans:bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<beans:property name="sessionFactory" ref="hibernate4AnnotatedSessionFactory" />
</beans:bean>
and queries in dao impl are like this
#Override
public void addObject(Object p) {
Session session = this.sessionFactory.getCurrentSession();
session.persist(p);
logger.info("Customer saved successfully, Customer Details=" + p);
}
The Exam users will login to application and he have to attempt 20 questions
The application is in my local machine and which is connected with in network for testing While the Exam is started with two people I am getting the problem like below
Exam pattern is to attempt 20 questions if two people started exam suppose one attempted 10 questions and other attempted 10 questions then the exam is getting completed I am thinking that the session is divided between the users can any one help me how can I overcome this problem.
I need to create a "keep me signed-in" functionality, my application is currently using spring 2.5, I checked it on :
http://docs.spring.io/autorepo/docs/spring-security/3.0.x/reference/remember-me.html#remember-me-persistent-token
which tells about the remember-me tag which does it part, I also tried extending AbstractPreAuthenticatedProcessingFilter but I'm unable to get through.
Can someone please guide me to the solution for the requirement.
Any help would be highly appreciated.
Thanks,
Vaibhav
This can simply be accomplished using the Spring security remember me authentication mechanism. What I did was made changes in the application-context-security.xml added the tag
<remember-me services-ref="rememberMeServices" key="vaib1q2w3e4r5tazsxdc"/>
and
<beans:bean id="rememberMeProcessingFilter"
class="org.springframework.security.ui.rememberme.RememberMeProcessingFilter">
<beans:property name="rememberMeServices" ref="rememberMeServices" />
<beans:property name="authenticationManager" ref="authenticationManager" />
</beans:bean>
<beans:bean id="rememberMeServices"
class="org.springframework.security.ui.rememberme.TokenBasedRememberMeServices">
<beans:property name="userDetailsService" ref="userDetailsService" />
<beans:property name="key" value="vaib1q2w3e4r5tazsxdc" />
<beans:property name="tokenValiditySeconds" value="120"/>
<beans:property name="alwaysRemember" value="false" />
</beans:bean>
<beans:bean id="rememberMeAuthenticationProvider"
class="org.springframework.security.providers.rememberme.RememberMeAuthenticationProvider">
<custom-authentication-provider />
<beans:property name="key" value="vaib1q2w3e4r5tazsxdc" />
</beans:bean>
By adding the above a new cookie by the name 'SPRING_SECURITY_REMEMBER_ME_COOKIE' would be created and would make things work like charm.
Thanks,
-V
When I make an implementation for
org.springframework.security.core.userdetails.UserDetailsService
and use the statement
sessionRegistry.registerNewSession(user.getUsername(), user);
within it after successful authentication, then the
sessionRegistry.getAllPrincipals();
list is not empty (but when I log out from application the session still remain within list) otherwise this list will be empty. how can I make the session registration (and also unregistration during user log out or session expiration) within sessionRegistry automatically? my spring config is as below:
<sec:http auto-config="true" use-expressions="true" access-denied-page="/accessDenied.jsf">
<sec:form-login login-page="/login.jsf" />
<sec:session-management session-authentication-strategy-ref="sas" />
</sec:http>
<bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<bean id="scr"
class="org.springframework.security.web.context.HttpSessionSecurityContextRepository" />
<bean id="smf"
class="org.springframework.security.web.session.SessionManagementFilter">
<constructor-arg name="securityContextRepository"
ref="scr" />
<property name="sessionAuthenticationStrategy"
ref="sas" />
</bean>
<bean id="sas"
class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<constructor-arg name="sessionRegistry"
ref="sessionRegistry" />
<property name="maximumSessions" value="10" />
</bean>
Most likely you have forgotten to add an HttpSessionEventPublisher to your web.xml.
Another possibility is that the principal in question has other sessions still active which haven't timed-out or been invalidated. You have a maximum session value of 10. Try setting that to "1" instead for testing.
Also, version 3.0.5 is out of date. You should use the latest version and keep up to date with patches to avoid vulnerabilities.
We have two web applications. Both are enabled with CAS authentication. We can navigate from web application(Application A) to another one(Application B). Some times sessionManagementFilter is redirecting to session expired page ,when user navigating from Application A to B.We are getting session invalid page for Application B. Here is our spring configuration settings in applicationContext-security.xml file.
Any idea what is the causing the issue. Prompt response is appreciable.
<http entry-point-ref="casProcessingFilterEntryPoint" >
<custom-filter position="CAS_FILTER" ref="casProcessingFilter" />
<custom-filter ref="sessionManagementFilter" before="SESSION_MANAGEMENT_FILTER" />
<logout logout-url="/j_spring_security_logout.xhtml" logout-success-url="calltoolSecurity{CAS_URL}/logout" invalidate-session="true" />
</http>
<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="actInvalidSessionStrategy" />
</beans:bean>
<beans:bean id="actInvalidSessionStrategy" class="com.avivausa.api.web.JsfRedirectStrategy">
<beans:constructor-arg name="invalidSessionUrl" value="/pages/system/errorSessionExpired.xhtml" />
</beans:bean>
Please make sure that both application using the same CAS server to login.
I spent a lot of time to solve this problem, yet still couldn't get it work.
I am using Spring Security. The application will run on multiple servers. I use the option "remember me" on login to save persistent logins in my database.
If a user is connected to server 1, he has a session id in cookies browser. I turn on another server and this user makes authentication and the cookies browser have this session id and the session id of server 1 connection.
When this user logs out in one server or another server, he should be redirected to login page in all servers.
I tried to remove cookies from browser without success. How can I make this work? Any help?
Example scenario: In gmail, if you have 2 tabs open in your account and if you log out from one of them, other tab automatically logs out too. The server 1 doesn't know the information of server 2.. I think my problem is here but I don't know how I can solve this.
This is my security config:
<http auto-config="false" use-expressions="true" disable-url-rewriting="true">
<intercept-url pattern="/login.do" access="permitAll" />
<intercept-url pattern="/**" access="hasRole('ROLE_USER')" />
<remember-me data-source-ref="dataSource" />
<form-login login-page="/login.do" />
<custom-filter position="CONCURRENT_SESSION_FILTER" ref="concurrencyFilter" />
<custom-filter position="LOGOUT_FILTER" ref="logoutFilter" />
<session-management session-authentication-strategy-ref="sas" />
</http>
<!-- <logout logout-url="/j_spring_security_logout" logout-success-url="/" invalidate-session="true" /> -->
<beans:bean id="logoutFilter" class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg value="/login.do" />
<beans:constructor-arg>
<beans:list>
<beans:ref bean="rememberMeServices"/>
<beans:ref bean="logoutHandler"/>
</beans:list>
</beans:constructor-arg>
<!-- <beans:property name="filterProcessesUrl" value="/login.do" /> -->
</beans:bean>
<beans:bean id="sessionRegistry" class="org.springframework.security.core.session.SessionRegistryImpl" />
<beans:bean id="concurrencyFilter" class="org.springframework.security.web.session.ConcurrentSessionFilter">
<beans:property name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="expiredUrl" value="/login.do" />
</beans:bean>
<beans:bean id="sas" class="org.springframework.security.web.authentication.session.ConcurrentSessionControlStrategy">
<beans:constructor-arg name="sessionRegistry" ref="sessionRegistry" />
<beans:property name="maximumSessions" value="1" />
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref="jdbcUserService" />
</authentication-manager>
Here are 3 solutions for your multiple-server scenario:
Use sticky sessions on your load balancer so the user keeps going back to the same server. Then you just invalidate the session when they log out. This is usually coupled with a session failover solution (Tomcat example) so if a server goes down a user can get redirected to a new server that picks up their old session.
Use a distributed cache for sessions (for example Terracotta Web Sessions). Then when they logout invalidate the session and it will be invalidated everywhere.
Another solution is to use a customized Spring Security TokenBasedRememberMeServices as your "login" cookie. If the user does not select remember me, go ahead and set the cookie, but make it a browser session cookie instead of a persistent cookie. All servers will recognize the user and create a session for it. When the user logs out, drop the cookie. You'll also need a custom RememberMeAuthenticationFilter that looks for a authentication token in the session and a missing RememberMe cookie, invalidating the session and clearing security context if that is the case.
I would recommend you to have a look at SessionRegistry .You can check this here . There has been a discussion on this at Is it possible to invalidate a spring security session? . Check this out too
Spring sessions are stored as JsessionID cookies. Check here for a discussion on cookie removal.
The same query has been discussed at Invalid a session when user makes logout (Spring).