开发者

How to add multiple custom-filter in Spring Security 3?

I need add two custom filters for FORM_LOGIN_FILTER, e.g.

<开发者_StackOverflow中文版;custom-filter after="FORM_LOGIN_FILTER" ref="myUsernamePasswordAuthenticationFilter" />
<custom-filter after="FORM_LOGIN_FILTER" ref="myUsernamePasswordAuthenticationFilter2" />

What I expect the filter sequences is:

1. Predefind FORM_LOGIN_FILTER

2. myUsernamePasswordAuthenticationFilter

3. myUsernamePasswordAuthenticationFilter2

But above will cause configuration error. So, anyone knows how to write the right config? Thanks!


Use Spring's CompositeFilter to wrap your custom filters list, and then put that filter on relevant position on SecurityFilterChain.

E.g. like this:

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


Do this:

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

That should put them where you want them.


I solved it like this:

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

}

Then in the context XML i have:

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

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜