Forbid spring boot add a filter with #Bean to filterchain - spring

I create a filter for shiro, use #Bean, but spring boot add it to servlet filterchain.
I used it in shiro filterChainDefinitions:
shiroFilterFactoryBean.getFilters().put("apiValid", getApiValidFilter());
#Bean(name = "apiValid")
public ApiValidFilter getApiValidFilter() {
return new ApiValidFilter();
}
I want the filter as a spring bean, to get benefit from spring, like use #Autowired, but do not want it add to filterchain automatic.
How to config spring boot to pervent this behavior?

As described in the documentation, you can create a FilterRegistrationBean for the Filter and mark it as disabled:
#Bean
public FilterRegistrationBean registration(MyFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}

Related

ServletRegistrationBean in Spring cloud

I have recently migrated the application to Spring Cloud Gateway from zuul filter for routing to multiple microservices. I have a filter which is written in
native code (HTTPServlet). In Spring application initialization, I am registering that Servlet as below
#Bean
public ServletRegistrationBean oAuthCodeReceiverServletBean() {
ServletRegistrationBean oauthCodeReceiverServletBean = new ServletRegistrationBean(
new OAuthCodeRecieverServlet(), "/login/oauth/codereceiver");
return oauthCodeReceiverServletBean;
}
#Bean
public FilterRegistrationBean<OAuthFilter> securityRegistrationBean() {
FilterRegistrationBean<OAuthFilter> registrationBean = new FilterRegistrationBean<>(oAuthFilter);
registrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
But the Filter is not at all called. The filters that implements GlobalFilter are called. Is there a solution handle ?
Please note I dont have option to update the native code OauthFilter.

Spring boot MessageDispatcherServlet overriding DispatcherServlet. how to skip overriding and register both DispatcherServlet?

in a single application, I m trying to use soap as well as rest web service. and each servlet is given different URI, below is the code of config class.
The question is: only soap service URL is working fine but for the rest on getting 405 error.
#EnableWs
#Configuration
public class WebServiceConfig {
#Bean
public ServletRegistrationBean RsRegistrationBean(ApplicationContext applicationContext) {
DispatcherServlet servlet = new DispatcherServlet();
servlet.setApplicationContext(applicationContext);
return new ServletRegistrationBean(servlet,"/rest/*");
}
#Bean
public ServletRegistrationBean<MessageDispatcherServlet> messageDispatcherServlet(
ApplicationContext context) {
MessageDispatcherServlet messageDispatcherServlet = new MessageDispatcherServlet();
messageDispatcherServlet.setApplicationContext(context);
messageDispatcherServlet.setTransformWsdlLocations(true);
return new ServletRegistrationBean<>(messageDispatcherServlet,"/");
}
}
Remove your WebServiceConfig class, as both are auto-configured by Spring Boot already (as of Spring Boot 1.4). Add the following to your application.properties
spring.mvc.servlet.path=/rest
spring.webservices.path=/
Now you leverage the Spring Boot proivded infrastructure instead of fighting with it.

SpringBoot Spring Security can't have a given filter applied to only one path [duplicate]

I want to use #Autowire with a Filter. So I define my filter in the SecurityConfig as below:
#Override
protected void configure(HttpSecurity http) throws Exception {
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
http.addFilterBefore(getA(), BasicAuthenticationFilter.class);
http.csrf().disable();
}
#Bean
public A getA(){
return new A();
}
This filter A extends Spring's GenericFilterBean.
I get below output when I invoke the controller, which shows the filter hits twice.
filter A before
filter A before
mycontroller invoke
filter A after
filter A after
My observation is, this extra invocation invoke with Spring container because if filter is not register as bean, it only get hits once. What is the reason and how can I fix it?
As you have observed, Spring Boot will automatically register any bean that is a Filter with the servlet container. One option is to not expose your filter as a bean and only register it with Spring Security.
If you want to be able to autowire dependencies into your Filter then it needs to be a bean. That means you need to tell Spring Boot not to register it as a filter. As described in the documentation, you do that using a FilterRegistrationBean:
#Bean
public FilterRegistrationBean registration(MyFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}
If you are on Spring 6.0.2 or plus version and if using OncePerRequestFilter,
Overriding shouldNotFilter method as follows will work.
#Override
protected boolean shouldNotFilter(HttpServletRequest request) {
return request.getServletPath().contains("/api/path/which/needs/to/exclude");
}
Removing #Component from the filter class helped me.
public class AuthTokenFilter extends OncePerRequestFilter {
}

How to integrate Spring Boot and Resteay

Although there are a lot of code example on the internet of integrating Spring Boot/Spring and Resteasy, but most of them are out of data or even don't work.
I am look at the latest Resteasy document, try to create a instance of SpringBeanProcessorServletAware in my config bean.
#Bean
public ServletListenerRegistrationBean<ResteasyBootstrap> resteasyBootstrapRegistratio() {
ServletListenerRegistrationBean<ResteasyBootstrap> registration = new ServletListenerRegistrationBean<>();
registration.setListener(new ResteasyBootstrap());
return registration;
}
#Bean
public ServletRegistrationBean resteasyServletRegistratio() {
ServletRegistrationBean registration = new ServletRegistrationBean();
registration.setServlet(new HttpServletDispatcher());
registration.addUrlMappings("/*");
return registration;
}
#Bean
public SpringBeanProcessorServletAware springBeanProcessorServletAware() {
SpringBeanProcessorServletAware springBeanProcessor = new SpringBeanProcessorServletAware();
return springBeanProcessor;
}
But it will throw Nullpoint exception. It seems like the servletContext is required to make SpringBeanProcessorServletAware work.
Then I try to inject servletContext. But the bean SpringBeanProcessorServletAware is being created before ServletContextInitializer finished.
How to make some bean created after ServletContextInitializer is finished?
Am I wrong in do the integration between Spring Boot and Resteasy.

Invoke a filter before spring security filter chain in boot

I have configured my filter as below but it doesn't get invoked before Spring Security Filter chain. I have set the order as zero
I'm using Spring Boot 1.3 which support setting order on filter
#Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(new UrlRewriteFilter());
registrationBean.addUrlPatterns("*");
registrationBean.addInitParameter("confReloadCheckInterval", "5");
registrationBean.addInitParameter("logLevel", "DEBUG");
registrationBean.addInitParameter("confPath", "urlrewrite.xml");
registrationBean.setOrder(0);
return registrationBean;
}
application.properties
security.filter-order=5
//>spring 2.1.3
spring.security.filter-order=5
These properties change from time to time and can be found here
https://docs.spring.io/spring-boot/docs/current/reference/html/appendix-application-properties.html#actuator-properties
I haven't done this myself but looking at the code it appears you simply need to set a property for the order of the security filter. For example in application.properties
This should order your filter before the security filter. I don't know what the implications are of changing this order as far as security goes it feels a bit risky to me. There is a discussion amongst the Spring developers about this here. It ends up in them implementing what my answer was above.
Discussion
https://github.com/spring-projects/spring-boot/issues/1640
Test showing what this property does.(search for testCustomFilterOrder())
https://github.com/spring-projects/spring-boot/blob/1.2.x/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/security/SecurityAutoConfigurationTests.java
The best way I have found to do this in SpringBoot 2.0 is in your Spring Security Configuration using addFilterBefore. I chose to do it before the Username Password filter as my filter was an alternative login filter
#Configuration
#EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(new UrlRewriteFilter(), UsernamePasswordAuthenticationFilter.class)
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/*/**").permitAll()
.antMatchers("/api/login").permitAll()
.antMatchers("/api/**").access("hasRole('ROLE_ADMIN')");
}
}
If you don't feel like choosing an arbitrary order for the security filter chain in the application.properties file, you can set the order using the SecurityProperties.DEFAULT_FILTER_ORDER value. This is the value used by the security filter chain since it doesn't explicitly set an order value.
#Bean
public FilterRegistrationBean<MyFilter> myFilterRegistration() {
FilterRegistrationBean<MyFilter> regBean= new FilterRegistrationBean<>();
regBean.setFilter(new MyFilter());
regBean.addUrlPatterns("/*");
// Invoke MyFilter before the security filter chain
regBean.setOrder(SecurityProperties.DEFAULT_FILTER_ORDER - 1);
return regBean;
}

Resources