Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Do I Use SessionDestroyedEvent?

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()).

like image 815
snowfi6916 Avatar asked Nov 07 '12 15:11

snowfi6916


2 Answers

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.

like image 133
axtavt Avatar answered Oct 24 '22 10:10

axtavt


This link may solve your problem.

HttpSessionEventPublisher and your service class both has to be under "Spring Root WebApplicationContex".

like image 33
Ketan Avatar answered Oct 24 '22 12:10

Ketan