【问题标题】:How to add multiple custom-filter in Spring Security 3?如何在 Spring Security 3 中添加多个自定义过滤器?
【发布时间】:2010-08-26 15:52:08
【问题描述】:

我需要为 FORM_LOGIN_FILTER 添加两个自定义过滤器,例如

<custom-filter after="FORM_LOGIN_FILTER" ref="myUsernamePasswordAuthenticationFilter" />
<custom-filter after="FORM_LOGIN_FILTER" ref="myUsernamePasswordAuthenticationFilter2" />

我期望的过滤器序列是:
1. 预定义FORM_LOGIN_FILTER
2. myUsernamePasswordAuthenticationFilter
3. myUsernamePasswordAuthenticationFilter2

但是上面会导致配置错误。 那么,有人知道如何编写正确的配置吗? 谢谢!

【问题讨论】:

    标签: java spring spring-security


    【解决方案1】:

    使用 Spring 的 CompositeFilter 包装您的自定义过滤器列表,然后将该过滤器放在 SecurityFilterChain 上的相关位置。

    例如像这样:

    <bean id="customFilters" class="org.springframework.web.filter.CompositeFilter">
        <property name="filters">
            <list>
                <ref bean="myUsernamePasswordAuthenticationFilter"/>
                <ref bean="myUsernamePasswordAuthenticationFilter2"/>
            </list>
        </property>
    </bean>
    ...
    <custom-filter after="FORM_LOGIN_FILTER" ref="customFilters" />
    

    【讨论】:

    • 很高兴有一个解决方案,但允许 bean refs 代替 Enum 值用于之前/之后属性会很好
    • 这是问题的正确答案,应该选择一个。谢谢!
    • 正确答案,过滤器bean也可以配置请求匹配器模式
    • 这一定是答案!
    【解决方案2】:

    这样做:

    <custom-filter after="FORM_LOGIN_FILTER" ref="myUsernamePasswordAuthenticationFilter" />
    <custom-filter before="BASIC_AUTH_FILTER" ref="myUsernamePasswordAuthenticationFilter2" />
    

    这应该把它们放在你想要的地方。

    【讨论】:

    • 非常感谢!这可能是一个不错的解决方案。但是如果我想要两个在 FORM_LOGIN_FILTER 和 BASIC_AUTH_FILTER 之间添加两个或更多自定义过滤器怎么办?有没有提供解决方案?再次感谢。
    【解决方案3】:

    我是这样解决的:

    public class QmLoginFilterWrapper extends GenericFilterBean implements ApplicationEventPublisherAware,
        MessageSourceAware
    {
      private static final Logger                          LOGGER     = LoggerFactory.getLogger(QmLoginFilterWrapper.class);
    
      private List<AbstractAuthenticationProcessingFilter> filterList = new ArrayList<AbstractAuthenticationProcessingFilter>();
    
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, final FilterChain chain) throws IOException,
          ServletException
      {
        FilterChain filterChain = new FilterChain() {
    
          @Override
          public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException
          {
            chain.doFilter(arg0, arg1);
    
          }
        };
        Vector<FilterChain> filterChains = new Vector<FilterChain>();
        filterChains.add(filterChain);
        if (LOGGER.isDebugEnabled())
        {
          LOGGER.debug("Filtering {} filters", filterList.size());
        }
        for (final GenericFilterBean filter : filterList)
        {
          final FilterChain lastChain = filterChains.lastElement();
          FilterChain loopChain = new FilterChain() {
    
            @Override
            public void doFilter(ServletRequest arg0, ServletResponse arg1) throws IOException, ServletException
            {
              if (LOGGER.isDebugEnabled())
              {
                LOGGER.debug("running filter {}", filter.getClass().getName());
              }
              filter.doFilter(arg0, arg1, lastChain);
            }
          };
          filterChains.add(loopChain);
        }
        filterChains.lastElement().doFilter(request, response);
      }
    
      @Override
      public void setMessageSource(MessageSource messageSource)
      {
        for (MessageSourceAware filter : filterList)
        {
          filter.setMessageSource(messageSource);
        }
      }
    
      @Override
      public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher)
      {
        for (ApplicationEventPublisherAware applicationEventPublisherAware : filterList)
        {
          applicationEventPublisherAware.setApplicationEventPublisher(applicationEventPublisher);
        }
      }
    
      public List<AbstractAuthenticationProcessingFilter> getFilterList()
      {
        return filterList;
      }
    
      public void setFilterList(List<AbstractAuthenticationProcessingFilter> filterList)
      {
        this.filterList = filterList;
        Collections.reverse(this.filterList);
      }
    
    }
    

    然后在我的上下文 XML 中:

      <bean id="qmAuthFilter" class="com.qmplus.common.logon.QmLoginFilterWrapper">
        <property name="filterList">
          <list>
            <ref local="samlProcessingFilter" />
            <ref local="usernamePasswordAuthenticationFilter" />
          </list>
        </property>
      </bean>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-27
      • 2019-12-25
      • 1970-01-01
      • 2011-08-23
      • 2014-07-28
      • 2014-08-13
      • 1970-01-01
      • 2016-04-26
      相关资源
      最近更新 更多