![](/img/trans.png)
[英]Prevent Spring Boot from registering one of Spring Security filter
[英]Prevent Spring Boot from registering a servlet filter
我有一個 Spring Boot WebMVC 應用程序和一個繼承自 AbstractPreAuthenticatedProcessingFilter 的 bean,我明確將其添加到 Spring 安全過濾器鏈中的特定位置。 我的 Spring 安全配置如下所示:
<http pattern="/rest/**">
<intercept-url pattern="/**" access="ROLE_USER"/>
<http-basic/>
<custom-filter after="BASIC_AUTH_FILTER" ref="preAuthenticationFilter"/>
</http>
<beans:bean id="preAuthenticationFilter" class="a.b.PreAuthenticationFilter">
<beans:property name="authenticationManager" ref="customAuthenticationManager"/>
</beans:bean>
安全配置有效。 問題是,因為 PreAuthenticationFilter class 繼承自 AbstractPreAuthenticatedProcessingFilter,Spring Boot 將其視為通用 servlet 過濾器,並將其添加到所有請求的 servlet 過濾器鏈中。 我不希望此過濾器成為所有請求的過濾器鏈的一部分。 我只希望它成為我配置的特定 Spring 安全過濾器鏈的一部分。 有沒有辦法阻止 Spring Boot 自動將 preAuthenticationFilter bean 添加到過濾器鏈?
默認情況下,Spring Boot會為應用程序上下文中的每個Filter
創建一個FilterRegistrationBean
,而FilterRegistrationBean
尚不存在。 這允許您通過為Filter
聲明自己的FilterRegistrationBean
來控制注冊過程,包括禁用注冊。 對於PreAuthenticationFilter
,所需的配置如下所示:
@Bean
public FilterRegistrationBean registration(PreAuthenticationFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}
您可能還對此Spring Boot問題感興趣, 該問題討論了如何禁用Filter
和Servlet
bean的自動注冊。
如果您想一次取消注冊所有過濾器,這是我的訣竅:
public class DefaultFiltersBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory bf)
throws BeansException {
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf;
Arrays.stream(beanFactory.getBeanNamesForType(javax.servlet.Filter.class))
.forEach(name -> {
BeanDefinition definition = BeanDefinitionBuilder
.genericBeanDefinition(FilterRegistrationBean.class)
.setScope(BeanDefinition.SCOPE_SINGLETON)
.addConstructorArgReference(name)
.addConstructorArgValue(new ServletRegistrationBean[]{})
.addPropertyValue("enabled", false)
.getBeanDefinition();
beanFactory.registerBeanDefinition(name + "FilterRegistrationBean",
definition);
});
}
}
關於這種技術的更多信息 - 這里 。
如果您需要禁用注冊 2 個過濾器(就像我所做的那樣),請包含 bean 的名稱(這樣它們就不會覆蓋):
@Bean(name = "filterRegistrationBean1")
public FilterRegistrationBean<YourFilter1> registration(YourFilter1 f1) {
FilterRegistrationBean<YourFilter1> registration = new FilterRegistrationBean<>(f1);
registration.setEnabled(false);
return registration;
}
@Bean(name = "filterRegistrationBean2")
public FilterRegistrationBean<YourFilter2> registration(YourFilter2 f2) {
FilterRegistrationBean<YourFilter2> registration = new FilterRegistrationBean<>(f2);
registration.setEnabled(false);
return registration;
}
我使用 aop 來做到這一點,使用 around pointcut 來連接你的過濾器,手動調用filterChain.doFilter(request, response)
@Aspect
@Component
public class AspectDemo {
@Around(value = "com.xxx.pointcut01()")
public void around01(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("[Aspect-around01] start");
ServletRequest request = (ServletRequest)Arrays.asList(
((MethodInvocationProceedingJoinPoint) joinPoint).getArgs()
).get(0);
ServletResponse response = (ServletResponse)Arrays.asList(
((MethodInvocationProceedingJoinPoint) joinPoint).getArgs()
).get(1);
FilterChain filterChain = (FilterChain)Arrays.asList(
((MethodInvocationProceedingJoinPoint) joinPoint).getArgs()
).get(2);
filterChain.doFilter(request, response);
//do not execute origin doFilter() method
//joinPoint.proceed();
System.out.println("[Aspect-around01] end");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.