【问题标题】:Filter from web.xml is not executed after migration of Spring Security迁移 Spring Security 后不执行来自 web.xml 的过滤器
【发布时间】:2015-02-19 05:23:22
【问题描述】:

我的 web.xml 文件中定义了几个过滤器。问题是我从 Spring Security 3.0.5 迁移到 3.2.5 之后,Spring 的 DelegatingFilterProxy 之后声明的过滤器没有执行。

...
<filter>
    <filter-name>noCacheHeaderFilter</filter-name>
    <filter-class>com.domain.web.filter.NoCacheHeaderFilter</filter-class>
</filter>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<!-- not executed bellow ->
<filter>   
    <filter-name>traceFilter</filter-name>
    <filter-class>com.domain.web.filter.TraceFilter</filter-class>
</filter>
...

这是安全配置文件:

<http auto-config="false" disable-url-rewriting="false">
    <intercept-url pattern="/server/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/includes/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <!--    may be needed later <intercept-url pattern="/static/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>-->
    <intercept-url pattern="/favicon.ico" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/error.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/index.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/users/password" access="IS_AUTHENTICATED_ANONYMOUSLY" method="PUT"/>
    <intercept-url pattern="/test.html" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/Silverlight.js" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/ClientBin/**/*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/help/**/*" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/components/download/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/>
    <intercept-url pattern="/**" access="ROLE_USER"/>
    <custom-filter ref="unsuccessfulBasicAuthenticationFilter" position="BASIC_AUTH_FILTER"/>
    <!--http-basic /-->
    <form-login login-processing-url="/login"
                authentication-failure-handler-ref="authenticationFailureHandlerService"
                authentication-success-handler-ref="loginSuccessHandler"/>
    <logout logout-url="/logout" success-handler-ref="logoutSuccessHandler"/>

</http>

此错误发生在“*/login”网址上。有人可以解释我做错了什么吗?

更新

这是 loginSuccessHandler 的代码:

@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
    if (authentication != null) {
        String redirectUrl = "";
        HttpSession session = request.getSession(false);
        if (session != null) {
            SavedRequest savedRequest = (SavedRequest) session.getAttribute("SPRING_SECURITY_SAVED_REQUEST_KEY");
            if (savedRequest != null) {
                redirectUrl = savedRequest.getRedirectUrl();
            }
        }

        User user = ((NgnmsUserDetails)(authentication.getPrincipal())).getUser();
        //if status user, do not add an event (status user is used by status script, to check if NMS is available)
        if(user != null && !user.getLogin().equals(User.STATUS_USER)) { 
            WebAuthenticationDetails details = (WebAuthenticationDetails)SecurityContextHolder.getContext().getAuthentication().getDetails();
            user.setSessionId(details.getSessionId());
            userService.updateUser(user);
            if (redirectUrl == null || !redirectUrl.contains("/ws/")){
                User.setCurrent(user);
                threadedApplicationEventPublisher.publishEvent(new UserLoginPostEvent(this, user, request.getRemoteAddr()));
            }
        }
    }
    super.onAuthenticationSuccess(request, response, authentication);
}

在调试中,此代码返回没有任何问题,但是在未调用 UsernamePasswordAuthenticationFilter 之后,spring security 自己的链中没有其他过滤器。

这里是 spring security 的调试输出:

24-Dec-2014 12:43:23,357 DEBUG [FilterChainProxy:http-192.168.143.119-8090-1] /login at position 1 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'
24-Dec-2014 12:43:23,358 DEBUG [HttpSessionSecurityContextRepository:http-192.168.143.119-8090-1] No HttpSession currently exists
24-Dec-2014 12:43:23,368 DEBUG [HttpSessionSecurityContextRepository:http-192.168.143.119-8090-1] No SecurityContext was available from the HttpSession: null. A new one will be created.
24-Dec-2014 12:43:23,370 DEBUG [FilterChainProxy:http-192.168.143.119-8090-1] /login at position 2 of 11 in additional filter chain; firing Filter: 'LogoutFilter'
24-Dec-2014 12:43:23,370 DEBUG [FilterChainProxy:http-192.168.143.119-8090-1] /login at position 3 of 11 in additional filter chain; firing Filter: 'UsernamePasswordAuthenticationFilter'
24-Dec-2014 12:43:23,371 DEBUG [UsernamePasswordAuthenticationFilter:http-192.168.143.119-8090-1] Request is to process authentication
24-Dec-2014 12:43:23,372 DEBUG [ProviderManager:http-192.168.143.119-8090-1] Authentication attempt using com.domain.security.impl.springsecurity.RandTechAuthenticationProvider
24-Dec-2014 12:43:23,405 DEBUG [CompositeSessionAuthenticationStrategy:http-192.168.143.119-8090-1] Delegating to org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy@5259817a
24-Dec-2014 12:43:23,406 DEBUG [UsernamePasswordAuthenticationFilter:http-192.168.143.119-8090-1] Authentication success. Updating SecurityContextHolder to contain: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@365ec150: Principal: com.domain.security.impl.springsecurity.NgnmsUserDetails@72439ad2; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@59b2: RemoteIpAddress: 192.168.143.119; SessionId: null; Granted Authorities: ROLE_USER
24-Dec-2014 12:43:23,429 DEBUG [root:main] preRegister called. Server=com.sun.jmx.mbeanserver.JmxMBeanServer@149ee0f1, name=log4j:logger=root
24-Dec-2014 12:43:23,501 DEBUG [DefaultRedirectStrategy:http-192.168.143.119-8090-1] Redirecting to '/index.html'
24-Dec-2014 12:43:23,502 DEBUG [HttpSessionSecurityContextRepository:http-192.168.143.119-8090-1] HttpSession being created as SecurityContext is non-default
24-Dec-2014 12:43:23,505 DEBUG [HttpSessionSecurityContextRepository:http-192.168.143.119-8090-1] SecurityContext stored to HttpSession: 'org.springframework.security.core.context.SecurityContextImpl@365ec150: Authentication: org.springframework.security.authentication.UsernamePasswordAuthenticationToken@365ec150: Principal: com.domain.security.impl.springsecurity.NgnmsUserDetails@72439ad2; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@59b2: RemoteIpAddress: 192.168.143.119; SessionId: null; Granted Authorities: ROLE_USER'
24-Dec-2014 12:43:23,505 DEBUG [SecurityContextPersistenceFilter:http-192.168.143.119-8090-1] SecurityContextHolder now cleared, as request processing completed

【问题讨论】:

    标签: servlets spring-security servlet-filters


    【解决方案1】:

    这听起来很正常。在处理完login 请求后,Spring Security 会调用你的loginSuccessHandler,它通常会进行重定向并返回。除了身份验证过滤器之外,过滤器链中的任何内容都不会被调用(包括您的web.xml 中的其他过滤器)。

    【讨论】:

    • 如果有重定向,那么我不相信它会有。但是,如果没有更多信息,就很难确定发生了什么,例如当您成功登录时调试日志中发生了什么以及您的 loginSuccessHandler 的代码实际上做了什么。
    • 再一次,这看起来和我预期的一样。用户在登录后立即被重定向到“/index.html”(通过调用super.onAuthenticationSuccess)。过滤器链的剩余部分isn't invoked for an authentication request
    猜你喜欢
    • 2019-10-01
    • 2013-09-18
    • 1970-01-01
    • 2011-08-23
    • 2014-07-28
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    相关资源
    最近更新 更多