views:

566

answers:

1

greetings all,iam using spring security 3 and i want to perform some logic(saving some data in the session) when the user is visiting the site and he's remembered so i extended the GenericFilterBean class and performed the logic in the doFilter method then complete the filter chain by calling the chain.doFilter method,and then inserted that filter after the remember me filter in the security.xml file?

but there's a problem is the filter is executed on each page even if the user is remembered or not is there's something wrong with the filter implementation or the position of the filter?

and i have a simple question,is the filter chain by default is executed on each page? and when making a custom filter should i add it to the web.xml too?

the filter class:

package projects.internal;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.GenericFilterBean;

import projects.ProjectManager;

public class rememberMeFilter extends GenericFilterBean {

    private ProjectManager projectManager;

    @Autowired
    public rememberMeFilter(ProjectManager projectManager) {
        this.projectManager = projectManager;
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {

        System.out.println("In The Filter");
        Authentication auth = (Authentication) SecurityContextHolder
                .getContext().getAuthentication();
        HttpServletResponse response = ((HttpServletResponse) res);
        HttpServletRequest request = ((HttpServletRequest) req);

        // if the user is not remembered,do nothing
        if (auth == null) {
            chain.doFilter(request, response);
        }

        else {
            // the user is remembered save some data in the session
            System.out.println("User Is Remembered");
            chain.doFilter(request, response);
        }
    }
}

the security.xml file:

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/security 
                        http://www.springframework.org/schema/security/spring-security-3.0.xsd"&gt;

    <global-method-security pre-post-annotations="enabled">

    </global-method-security>
    <http use-expressions="true" >
        <remember-me data-source-ref="dataSource"/> 
        <intercept-url pattern="/" access="permitAll" />
        <intercept-url pattern="/images/**" filters="none" />
        <intercept-url pattern="/scripts/**" filters="none" /> 
        <intercept-url pattern="/styles/**" filters="none" />
        <intercept-url pattern="/p/login" filters="none" />
        <intercept-url pattern="/p/register" filters="none" />
        <intercept-url pattern="/p/forgot_password" filters="none" />
        <intercept-url pattern="/p/**" access="isAuthenticated()" />
        <custom-filter after="REMEMBER_ME_FILTER" ref="rememberMeFilter" />

        <form-login login-processing-url="/j_spring_security_check"
            login-page="/p/login" authentication-failure-url="/p/login?login_error=1"
            default-target-url="/p/dashboard" authentication-success-handler-ref="myAuthenticationHandler"
            always-use-default-target="false" />

        <logout/> 
        </http>

    <beans:bean id="myAuthenticationHandler" class="projects.internal.myAuthenticationHandler" />
    <beans:bean id="rememberMeFilter" class="projects.internal.rememberMeFilter" >
    </beans:bean>

    <authentication-manager alias="authenticationManager">
        <authentication-provider>
            <password-encoder hash="md5" />
            <jdbc-user-service data-source-ref="dataSource" />

        </authentication-provider>
    </authentication-manager>
</beans:beans>

any help?

+1  A: 

I think your confusion comes from the fact that the Spring Security Filter Chain is a single ServletFilter, which contains it's own, internal, chain of SpringSecurityFilters. If you want to add a filter to the that chain you need to subclass SpringSecurityFIlter and implement it's doFilterHttp() method. In your case I might try to write a Pre-Authentication filter that does the logic you want. If no user object is found (hence there was none in the session) then it does some logic and then Spring Security goes on to authenticate the user. Check this out for a more detailed example Pre-Authentication Mechanism.

Gandalf