如何使用 AbstractSecurityWebApplicationInitial?
How to use an AbstractSecurityWebApplicationInitial?
我是 Spring 的新手,我对 MultipartFilter
和 CSRF 有疑问。我在 spring.io security docs 中发现您可以使用以下 class 将 MultipartFilter
放在安全过滤器之前,这样 MultiparFilter
就不会弄乱。我的问题是,虽然我有波纹管 class,但它似乎没有加载,例如日志消息没有出现。
我应该把 AbstractSecurityWebApplicationInitializer
subclass 放在某个特定的地方吗?是否需要添加其他配置或标签才能使用?
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.");
}
}
我也尝试过添加 @Configuration
注释,但结果相同(不好)(我想是因为没有任何 bean)。
正如您在下面看到的,我正在通过 Java 而不是 xml 配置它,如果可能的话我更愿意坚持使用它。
这是我的安全配置:
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();
}
}
我也试过 http.addFilterBefore
但它仍然抛出 CSRF 错误。
@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();
}
注意:我已经尝试使用 SecurityContextPersistenceFilter、LogoutFilter 和其他方法,但遇到了同样的问题。并使用 CorsFilter.class,但抛出异常 Error creating bean with name 'springSecurityFilterChain'
所以我认为你不能在使用此方法之前添加它。
这是选择在 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.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$8ef7.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(<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$7e2d9c.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
嗯,在深入了解CSRF和Spring后,我发现确实没有任何问题。这是我的一些结论。
- 由于我没有部署 servelet (war),因此未加载 AbstractSecurityWebApplicationInitializer。
- 当我在 CSRF 过滤器之前使用
MultipartFilter
时,它确实被添加和加载,如日志 Creating filter chain: Ant [pattern='/**'], [..., org.springframework.web.multipart.support.MultipartFilter@1357a33a, org.springframework.security.web.csrf.CsrfFilter@695fc2fc, ...]
所示。
- 最大的问题是我认为不需要包含 csrf 参数,因为它已自动包含。 如果包含它,它可以识别多部分的 CSRF 令牌!
现在我用CsrfTokenResponseHeaderBindingFilter
, like it is suggested in Spring Security’s CSRF protection for REST services: the client side and the server side to include the CSRF in the header (that is useful for a REST API). You could use other solutions like in With Spring Security 3.2.0.RELEASE, how can I get the CSRF token in a page that is purely HTML with no tag libs.
关于 multipartfilter 问题,您可以阅读其他问题,例如 Spring Security 3.2 CSRF support for multipart requests。
总而言之,Spring 中的一个 nob 提出的问题有点愚蠢,但这里是如果另一个 nob 想阅读它。
我是 Spring 的新手,我对 MultipartFilter
和 CSRF 有疑问。我在 spring.io security docs 中发现您可以使用以下 class 将 MultipartFilter
放在安全过滤器之前,这样 MultiparFilter
就不会弄乱。我的问题是,虽然我有波纹管 class,但它似乎没有加载,例如日志消息没有出现。
我应该把 AbstractSecurityWebApplicationInitializer
subclass 放在某个特定的地方吗?是否需要添加其他配置或标签才能使用?
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.");
}
}
我也尝试过添加 @Configuration
注释,但结果相同(不好)(我想是因为没有任何 bean)。
正如您在下面看到的,我正在通过 Java 而不是 xml 配置它,如果可能的话我更愿意坚持使用它。
这是我的安全配置:
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();
}
}
我也试过 http.addFilterBefore
但它仍然抛出 CSRF 错误。
@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();
}
注意:我已经尝试使用 SecurityContextPersistenceFilter、LogoutFilter 和其他方法,但遇到了同样的问题。并使用 CorsFilter.class,但抛出异常 Error creating bean with name 'springSecurityFilterChain'
所以我认为你不能在使用此方法之前添加它。
这是选择在 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.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$8ef7.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(<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$7e2d9c.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
嗯,在深入了解CSRF和Spring后,我发现确实没有任何问题。这是我的一些结论。
- 由于我没有部署 servelet (war),因此未加载 AbstractSecurityWebApplicationInitializer。
- 当我在 CSRF 过滤器之前使用
MultipartFilter
时,它确实被添加和加载,如日志Creating filter chain: Ant [pattern='/**'], [..., org.springframework.web.multipart.support.MultipartFilter@1357a33a, org.springframework.security.web.csrf.CsrfFilter@695fc2fc, ...]
所示。 - 最大的问题是我认为不需要包含 csrf 参数,因为它已自动包含。 如果包含它,它可以识别多部分的 CSRF 令牌!
现在我用CsrfTokenResponseHeaderBindingFilter
, like it is suggested in Spring Security’s CSRF protection for REST services: the client side and the server side to include the CSRF in the header (that is useful for a REST API). You could use other solutions like in With Spring Security 3.2.0.RELEASE, how can I get the CSRF token in a page that is purely HTML with no tag libs.
关于 multipartfilter 问题,您可以阅读其他问题,例如 Spring Security 3.2 CSRF support for multipart requests。
总而言之,Spring 中的一个 nob 提出的问题有点愚蠢,但这里是如果另一个 nob 想阅读它。