I am having a problem trying to get my SessionDestroyedEvent to work. I want it to print out whenever the session times out. I am clearing my history to force it to time out.
This is my code:
@Service
public class MyTimeoutFilter implements
ApplicationListener<ApplicationEvent>
{
public MyTimeoutFilter()
{
super();
System.out.println("Application context listener is created!");
}
public void onApplicationEvent(ApplicationEvent event)
{
if (event instanceof SessionDestroyedEvent)
{
SessionDestroyedEvent sdEvent = (SessionDestroyedEvent) event;
List<SecurityContext> lstSecurityContext = sdEvent
.getSecurityContexts();
for (SecurityContext securityContext : lstSecurityContext)
{
System.out.println("Security Context: "
securityContext.getAuthentication().getName());
}
}
System.out.println("This is a test.");
}
}
All I get is "Application context listener is created.", followed by "This is a test." I never have the code inside the if statement run.
Here is my web.xml:
<!-- The definition of the Root Spring Container shared by all Servlets
and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml,
/WEB-INF/spring/appServlet/security-context.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</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>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
I don't have a file called "application-context.xml". I do however have a "servlet-context.xml" and a "security-context.xml". Here is both:
Servlet-context.xml
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<annotation-driven />
<resources mapping="/static/**" location="/static/" />
<beans:bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.blahblahblah.bagbox" />
<context:property-placeholder location="classpath*:jdbc.properties" />
<mvc:annotation-driven />
<tx:annotation-driven />
<beans:bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
<beans:property name="order">
<beans:value>1</beans:value>
</beans:property>
</beans:bean>
<tx:annotation-driven transaction-manager="transactionManager" />
<beans:bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close" p:driverClass="${app.jdbc.driverClassName}"
p:jdbcUrl="${app.jdbc.url}" p:user="${app.jdbc.username}" p:password="${app.jdbc.password}"
p:acquireIncrement="5" p:idleConnectionTestPeriod="60" p:maxPoolSize="100"
p:maxStatements="50" p:minPoolSize="10" />
<beans:bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />
</beans:beans>
Here is my Security-context.xml
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:security="http://www.springframework.org/schema/security"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd">
<security:http auto-config="false" use-expressions="true"
entry-point-ref="loginUrlAuthenticationEntryPoint">
<security:intercept-url pattern="/login*"
access="isAnonymous()" />
<security:intercept-url pattern="/logout*"
access="isAnonymous()" />
<security:intercept-url pattern="/static/**"
access="permitAll" />
<security:intercept-url pattern="/**"
access="isFullyAuthenticated()" />
<security:intercept-url pattern="/"
access="isFullyAuthenticated()" />
<security:anonymous />
<security:custom-filter ref="loginFilter"
position="FORM_LOGIN_FILTER" />
<security:custom-filter position="LOGOUT_FILTER"
ref="logoutFilter" />
</security:http>
<beans:bean id="loginUrlAuthenticationEntryPoint"
class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:property name="loginFormUrl" value="/login.html" />
</beans:bean>
<beans:bean id="loginFilter"
class="com.blahblahblah.bagbox.security.filter.MyLoginFilter">
<beans:property name="authenticationManager" ref="authenticationManager" />
<beans:property name="authenticationFailureHandler"
ref="failureHandler" />
<beans:property name="authenticationSuccessHandler"
ref="successHandler" />
</beans:bean>
<beans:bean id="successHandler"
class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
<beans:property name="defaultTargetUrl" value="/" />
</beans:bean>
<beans:bean id="failureHandler"
class="org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler">
<beans:property name="defaultFailureUrl" value="/loginFailed.html" />
</beans:bean>
<beans:bean id="logoutFilter"
class="org.springframework.security.web.authentication.logout.LogoutFilter">
<beans:constructor-arg index="0" value="/login.html" />
<beans:constructor-arg index="1">
<beans:list>
<beans:bean id="securityContextLogoutHandler"
class="org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler" />
<beans:bean id="logoutHandler"
class="com.blahblahblah.bagbox.security.filter.MyLogoutHandler" />
</beans:list>
</beans:constructor-arg>
<beans:property name="filterProcessesUrl" value="/logout.html" />
</beans:bean>
<security:global-method-security
secured-annotations="enabled" />
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider
ref="ldapAuthProvider" />
</security:authentication-manager>
<beans:bean id="ldapAuthProvider"
class="org.springframework.security.ldap.authentication.LdapAuthenticationProvider">
<beans:constructor-arg>
<beans:ref local="bindAuthenticator" />
</beans:constructor-arg>
<beans:constructor-arg>
<beans:ref local="authoritiesPopulator" />
</beans:constructor-arg>
<beans:property name="userDetailsContextMapper" ref="userDetailsContextMapper" />
</beans:bean>
<beans:bean id="bindAuthenticator"
class="org.springframework.security.ldap.authentication.BindAuthenticator">
<beans:constructor-arg ref="initialDirContextFactory" />
<beans:property name="userSearch" ref="userSearch" />
</beans:bean>
<beans:bean id="authoritiesPopulator"
class="org.springframework.security.ldap.userdetails.DefaultLdapAuthoritiesPopulator">
<beans:constructor-arg ref="initialDirContextFactory" />
<beans:constructor-arg value="" />
<beans:property name="groupRoleAttribute" value="cn" />
<beans:property name="searchSubtree" value="true" />
<beans:property name="rolePrefix" value="ROLE_" />
<beans:property name="convertToUpperCase" value="true" />
</beans:bean>
<beans:bean id="userDetailsContextMapper"
class="org.springframework.security.ldap.userdetails.InetOrgPersonContextMapper" />
<beans:bean id="userSearch"
class="org.springframework.security.ldap.search.FilterBasedLdapUserSearch">
<beans:constructor-arg index="0" value="" />
<beans:constructor-arg index="1"
value="(sAMAccountName={0})" />
<beans:constructor-arg index="2"
ref="initialDirContextFactory" />
<beans:property name="searchSubtree" value="true" />
</beans:bean>
<beans:bean id="initialDirContextFactory"
class="org.springframework.security.ldap.DefaultSpringSecurityContextSource">
<beans:constructor-arg
value="ldap://ccpdc.countrycurtains.local:389/dc=countrycurtains,dc=local" />
<beans:property name="userDn"
value="CN=LDAP BIND,CN=Users,DC=countrycurtains,DC=local" />
<beans:property name="password" value="ld4pb1nd" />
<beans:property name="baseEnvironmentProperties">
<beans:map>
<beans:entry key="java.naming.referral">
<beans:value>follow</beans:value>
</beans:entry>
</beans:map>
</beans:property>
</beans:bean>
<beans:bean id="loggerListener"
class="org.springframework.security.authentication.event.LoggerListener" />
</beans:beans>
Can someone who has a lot of experience with SessionDestroyedEvent and/or getting session timeouts to work with Spring Security please help me. All of the code I have looked up on Google points me to methods that are no longer valid (such as getSecurityContext(), when it has been changed to getSecurityContexts()).
Don't forget to declare HttpSessionEventPublisher
in web.xml
:
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
Also I don't quite understand how clearing your history should force session to time out. If you want to test session timeout functionality you need to configure some small session timeout in web.xml
(for example, 1 minute), log in and wait until it times out.
This link may solve your problem.
HttpSessionEventPublisher and your service class both has to be under "Spring Root WebApplicationContex".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With