Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在SpringSecurity3中添加多个自定义过滤器?_Java_Spring_Spring Security - Fatal编程技术网

Java 如何在SpringSecurity3中添加多个自定义过滤器?

Java 如何在SpringSecurity3中添加多个自定义过滤器?,java,spring,spring-security,Java,Spring,Spring Security,我需要为表单\登录\过滤器添加两个自定义过滤器,例如 <custom-filter after="FORM_LOGIN_FILTER" ref="myUsernamePasswordAuthenticationFilter" /> <custom-filter after="FORM_LOGIN_FILTER" ref="myUsernamePasswordAuthenticationFilter2" /> 我所期望的过滤器序列是: 1.预定义表单\登录\过滤器 2

我需要为表单\登录\过滤器添加两个自定义过滤器,例如

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

我所期望的过滤器序列是:
1.预定义表单\登录\过滤器
2.myUsernamePasswordAuthenticationFilter
3.myUsernamePasswordAuthenticationFilter2

但以上操作将导致配置错误。 那么,有人知道如何编写正确的配置吗? 谢谢

这样做:

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

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

我是这样解决的:

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

}
<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" />
公共类QmLoginFilterWrapper扩展了GenericFilterBean实现ApplicationEventPublisherAware,
MessageSourceAware
{
私有静态最终记录器Logger=LoggerFactory.getLogger(QmLoginFilterWrapper.class);
私有列表过滤器列表=新的ArrayList();
@凌驾
public void doFilter(ServletRequest请求、ServletResponse响应、final FilterChain链)抛出IOException,
ServletException
{
FilterChain FilterChain=新的FilterChain(){
@凌驾
public void doFilter(ServletRequest arg0,ServletResponse arg1)引发IOException,ServletException
{
链式过滤器(arg0,arg1);
}
};
向量过滤器链=新向量();
filterChains.add(filterChain);
if(LOGGER.isDebugEnabled())
{
debug(“过滤{}过滤器”,filterList.size());
}
对于(最终通用筛选器Bean筛选器:筛选器列表)
{
final FilterChain lastChain=filterChains.lastElement();
FilterChain loopChain=新的FilterChain(){
@凌驾
public void doFilter(ServletRequest arg0,ServletResponse arg1)引发IOException,ServletException
{
if(LOGGER.isDebugEnabled())
{
debug(“运行过滤器{}”,filter.getClass().getName());
}
filter.doFilter(arg0、arg1、lastChain);
}
};
filterChains.add(环链);
}
filterChains.lastElement().doFilter(请求、响应);
}
@凌驾
public void setMessageSource(MessageSource MessageSource)
{
for(MessageSourceAware筛选器:筛选器列表)
{
filter.setMessageSource(messageSource);
}
}
@凌驾
公共无效设置ApplicationEventPublisher(ApplicationEventPublisher ApplicationEventPublisher)
{
for(ApplicationEventPublisherAware ApplicationEventPublisherAware:filterList)
{
applicationEventPublisherAware.setApplicationEventPublisher(applicationEventPublisher);
}
}
公共列表getFilterList()
{
返回过滤器列表;
}
公共空集合过滤器列表(列表过滤器列表)
{
this.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>

使用Spring的
复合过滤器
包装您的自定义过滤器列表,然后将该过滤器放在
安全过滤器链
的相关位置

例如,像这样:

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

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

...

非常感谢!这可能是一个很好的解决方案。但是,如果我想要两个,在FORM_LOGIN_FILTER和BASIC_AUTH_FILTER之间添加两个或更多自定义筛选器,该怎么办?是否提供了任何解决方案?再次感谢。很高兴有解决方案,但是最好允许bean refs而不是before/after属性的枚举值。这是问题的正确答案,应该选择一个。谢谢回答正确,过滤器bean也可以配置请求匹配器模式