在Spring Security Filter Chain之前设置Cookie

时间:2014-12-19 08:03:50

标签: java spring spring-security

我想设置一个引荐来源cookie,因为我需要排除一些页面(例如错误,登录,注销,...),以便能够在登录后重定向到最后一个被调用但未被排除的页面:

public class CookieReferrerFilter extends OncePerRequestFilter {
    public static final String REFERRER_COOKIE_NAME = "REFERRER";

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if (!isReferrerExcluded(request)) {
            Cookie sessionCookie = new Cookie(REFERRER_COOKIE_NAME, request.getRequestURI());
            sessionCookie.setPath(!"".equals(request.getContextPath()) ? request.getContextPath() : "/");
            sessionCookie.setSecure(false);
            sessionCookie.setMaxAge(-1);

            response.addCookie(sessionCookie);
        }

        filterChain.doFilter(request, response);
    }

    private boolean isReferrerExcluded(HttpServletRequest request) {
        for (String pattern : EXCLUDED_REFERRER) {
            if (new AntPathRequestMatcher(pattern).matches(request)) {
                return true;
            }
        }

        return false;
    }
}

但Spring Security Filter Chain在CookieReferrerFilter之前被触发。 因此,调用安全页面会立即将我重定向到登录页面而不调用CookieReferrerFilter.doFilterInternal,并且没有设置cookie。

有一个类配置webbapp(设置配置类,映射,过滤器),扩展了AbstractAnnotationConfigDispatcherServletInitializer

public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[] { ApplicationContextConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }

    @Override
    protected Filter[] getServletFilters() {
        CookieReferrerFilter cookieReferrerFilter = new CookieReferrerFilter();

        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        characterEncodingFilter.setForceEncoding(true);

        return new Filter[] { cookieReferrerFilter, characterEncodingFilter };
    }
}

另一个只是扩展AbstractSecurityWebApplicationInitializer

public class SecurityInitializer extends AbstractSecurityWebApplicationInitializer {
}

1 个答案:

答案 0 :(得分:3)

假设您正在使用基于Java的Spring Security配置,您可以让您的过滤器进行弹簧管理,并在Spring Security过滤器链的开头添加它(受HttpSecurity javadoc示例的启发)(见下文)一个链接):

 @Configuration
 @EnableWebSecurity
 public class HttpSecurityConfig extends WebSecurityConfigurerAdapter {

     @Autowired  CookieReferrerFilter cookieFilter;

     @Autowired CharacterEncodingFilter encodingFilter;

     @Override
     protected void configure(HttpSecurity http) throws Exception {
         http
             .addFilterBefore(cookieFilter, ChannelProcessingFilter.class)
             .addFilterBefore(encodingFilter, ChannelProcessingFilter.class)
               //your configuration follows here
                ; 
      }
   }

有关详细信息,请参阅http://docs.spring.io/autorepo/docs/spring-security/current/apidocs/org/springframework/security/config/annotation/web/builders/HttpSecurity.html#addFilter(javax.servlet.Filter)