开发者

How to perform custom logic with Spring Security when user is remembered?

I'm 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. I extended the GenericFilterBean class, perform the logic in the doFilter method, then complete the filter chain by calling the chain.doFilter method. I inserted that filter after the "remember me" filter in the security.xml file.

But the problem is that the filter is executed on each page regardless of whether the user is remembered or not. Is there something wrong with the filter implementation or the position of the filter?

Is the filter chain by default executed on each page? 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">

    <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?


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜