I'm new to Spring and I have a problem with MultipartFilter
and CSRF. I found in spring.io security docs that you can use the following class to put MultipartFilter
before the security filter so MultiparFilter
don't get mess. My problem is that although I have the bellow class, it appears to not be loaded, for example the log message doesn't appear.
Should I put AbstractSecurityWebApplicationInitializer
subclass in some specific place? Do I need to add other configurations or tags to use it?
package com.penalara.ghcserviceapi.config;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.security.web.context.AbstractSecurityWebApplicationInitializer;
import org.springframework.web.multipart.support.MultipartFilter;
public class SecurityApplicationInitializer extends AbstractSecurityWebApplicationInitializer {
public final static Log log = LogFactory.getLog(SecurityApplicationInitializer.class);
@Override
protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
insertFilters(servletContext, new MultipartFilter());
log.debug("Inicializados los filtros.");
}
}
I've also tried to put a @Configuration
annotation but with the same (bad) result (I think because there isn't any bean).
As you can see bellow I'm configuring it through Java instead of xml and I prefer to stick to it if possible.
This is my security configuration:
package com.penalara.ghcserviceapi.config;
import javax.servlet.ServletContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.web.filter.DelegatingFilterProxy;
import org.springframework.web.multipart.support.MultipartFilter;
import com.penalara.ghcserviceapi.model.security.CuentaUser;
import com.penalara.ghcserviceapi.repositories.CuentaRepository;
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Log log = LogFactory.getLog(SecurityConfig.class);
@Autowired
CuentaRepository accountRepository;
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService());
}
@Bean
public UserDetailsService userDetailsService() {
return (username) -> accountRepository
.findByUsuario(username)
.map(a -> new CuentaUser(a, AuthorityUtils.createAuthorityList("USER", "write")))
.orElseThrow(
() -> new UsernameNotFoundException("could not find the user '"
+ username + "'"));
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic();
}
}
I have also tried with http.addFilterBefore
but it still throw the CSRF error.
@Override
protected void configure(HttpSecurity http) throws Exception {
MultipartFilter mf = new MultipartFilter();
mf.setServletContext(context);
http.addFilterBefore(mf, SecurityContextPersistenceFilter.class);
http.authorizeRequests().anyRequest().authenticated().and().httpBasic();
}
Note: I have tried with SecurityContextPersistenceFilter, LogoutFilter, and others but with the same problem. And using CorsFilter.class, but throw a exception Error creating bean with name 'springSecurityFilterChain'
so I think you can't add it before with this method.
This is the stacktrace when choosing add before CorsFilter:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springSecurityFilterChain' defined in class path resource [org/springframework/security/config/annotation/web/configuration/WebSecurityConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: Cannot register after unregistered Filter class org.springframework.web.filter.CorsFilter
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:599) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1060) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:235) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:199) ~[spring-web-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:109) ~[tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4659) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5281) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:147) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) [tomcat-embed-core-8.0.32.jar:8.0.32]
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) [tomcat-embed-core-8.0.32.jar:8.0.32]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_91]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_91]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.servlet.Filter]: Factory method 'springSecurityFilterChain' threw exception; nested exception is java.lang.IllegalArgumentException: Cannot register after unregistered Filter class org.springframework.web.filter.CorsFilter
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
... 23 common frames omitted
Caused by: java.lang.IllegalArgumentException: Cannot register after unregistered Filter class org.springframework.web.filter.CorsFilter
at org.springframework.security.config.annotation.web.builders.FilterComparator.registerBefore(FilterComparator.java:163) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.config.annotation.web.builders.HttpSecurity.addFilterBefore(HttpSecurity.java:977) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at com.penalara.ghcserviceapi.config.SecurityConfig.configure(SecurityConfig.java:60) ~[classes/:na]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.getHttp(WebSecurityConfigurerAdapter.java:199) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:290) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter.init(WebSecurityConfigurerAdapter.java:67) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at com.penalara.ghcserviceapi.config.SecurityConfig$$EnhancerBySpringCGLIB$$978ef7.init(<generated>) ~[classes/:na]
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.init(AbstractConfiguredSecurityBuilder.java:370) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.config.annotation.AbstractConfiguredSecurityBuilder.doBuild(AbstractConfiguredSecurityBuilder.java:324) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.config.annotation.AbstractSecurityBuilder.build(AbstractSecurityBuilder.java:41) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration.springSecurityFilterChain(WebSecurityConfiguration.java:105) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$cdd84cf3.CGLIB$springSecurityFilterChain$2(<generated>) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$cdd84cf3$$FastClassBySpringCGLIB$$527e2d9c.invoke(<generated>) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:355) ~[spring-context-4.2.5.RELEASE.jar:4.2.5.RELEASE]
at org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration$$EnhancerBySpringCGLIB$$cdd84cf3.springSecurityFilterChain(<generated>) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_91]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_91]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_91]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_91]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:162) ~[spring-beans-4.2.5.RELEASE.jar:4.2.5.RELEASE]
... 24 common frames omitted