【问题标题】:How to perform custom logic with Spring Security when user is remembered?记住用户时如何使用 Spring Security 执行自定义逻辑?
【发布时间】:2011-02-04 05:43:59
【问题描述】:

我正在使用 Spring Security 3,并且我想在用户访问该站点并且他被记住时执行一些逻辑(在会话中保存一些数据)。我扩展了GenericFilterBean类,执行doFilter方法中的逻辑,然后调用chain.doFilter方法完成过滤器链。我在 security.xml 文件中的“记住我”过滤器之后插入了该过滤器。

但问题是过滤器在每个页面上执行,而不管用户是否被记住。过滤器的实现或者过滤器的位置有问题吗?

过滤器链是否默认在每个页面上执行? 在制作自定义过滤器时,我是否也应该将其添加到 web.xml 中?

过滤器类:

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);
        }
    }
}

security.xml 文件:

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

有什么帮助吗?

【问题讨论】:

    标签: spring spring-security servlet-filters


    【解决方案1】:

    我认为您的困惑来自这样一个事实,即 Spring Security 过滤器链是单个 ServletFilter,其中包含它自己的内部链 SpringSecurityFilters。如果要向该链添加过滤器,则需要继承 SpringSecurityFIlter 并实现它的 doFilterHttp() 方法。在您的情况下,我可能会尝试编写一个执行您想要的逻辑的预身份验证过滤器。如果没有找到用户对象(因此会话中没有),那么它会执行一些逻辑,然后 Spring Security 继续对用户进行身份验证。查看此内容以获取更详细的示例Pre-Authentication Mechanism

    【讨论】:

      猜你喜欢
      • 2012-01-14
      • 1970-01-01
      • 1970-01-01
      • 2016-08-02
      • 2013-03-29
      • 1970-01-01
      • 2018-05-23
      • 1970-01-01
      • 2023-03-05
      相关资源
      最近更新 更多