如何在Spring Boot中覆盖Spring Security默认配置

我对Spring Boot有一点问题。 我非常喜欢Spring Boot,它是非常方便的工具,它让我可以专注于逻辑实现而不是bean配置。 但是……我想覆盖默认的Spring Security配置。 我创建了SecurityConfig类,Spring Boot在启动时加载了该类。 我可以在地址/ bean上看到我的配置bean。

但配置仍然是默认的(我猜)。

@Configuration @EnableWebSecurity public class SecurityConfiguration extends WebSecurityConfigurerAdapter { public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{ auth.inMemoryAuthentication().withUser("user").password("password").roles("USER"); } protected void cofigure(HttpSecurity http) throws Exception{ http.authorizeRequests() .antMatchers("/app/").permitAll() .anyRequest().authenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll() .and() .csrf() .and() .exceptionHandling() .accessDeniedPage("/error"); } } 

我已使用username:user声明用户,并传递:password。 我还宣称,Spring Security必须允许任何用户查看索引站点:localhost:port / app /。

我想如果我在浏览器中输入localhost:port / app / url,Spring Security会让我进来。相反,我得到localhost:port / login页面和默认的Spring Security登录表单。 此外,在AuthenticationManager中声明的用户名和密码不起作用。

但是,如果我键入我的应用程序属性凭据,它就可以工作。

 security.user.name=testUser security.user.password=testPass security.user.role=USER 

结论:Spring Boot似乎加载了我的自定义Spring Securty配置,但它没有使用它。

为什么?

编辑:

现在我的SecurityConf看起来像这样:

 @Configuration @EnableWebSecurity @EnableGlobalMethodSecurity(securedEnabled = true) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{ auth.inMemoryAuthentication().withUser("user").password("password").roles("ROLE_USER"); } protected void cofigure(HttpSecurity http) throws Exception{ http .authorizeRequests() .antMatchers("/").permitAll() .antMatchers("/app/").permitAll() .and().formLogin(); } } 

pom.xml中:

   4.0.0 szczepanski.gerard spring-boot-edu-fm 0.0.1-SNAPSHOT jar SpringBootEduFreemarker Demo project for Spring Boot  org.springframework.boot spring-boot-starter-parent 1.3.2.RELEASE     UTF-8 1.8    org.springframework.boot spring-boot-starter-data-jpa   org.springframework.boot spring-boot-starter-freemarker   org.springframework.boot spring-boot-starter-security   org.springframework.boot spring-boot-starter-thymeleaf   org.springframework.boot spring-boot-starter-web   org.hsqldb hsqldb runtime   org.springframework.boot spring-boot-starter-actuator   org.springframework.boot spring-boot-devtools true   org.springframework.boot spring-boot-starter-test test   org.scala-lang scala-library 2.11.0      org.springframework.boot spring-boot-maven-plugin     

Spring Boot初始化时出现堆栈跟踪:

 org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.con fig.annotation.web.configuration.WebSecurityConfiguration': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springframework. security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.springfr amework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested exception is o rg.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.springframe work.beans.factory.BeanCreationException: Error creating bean with name 'securityConfiguration': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: ROLE_USER cannot start with ROLE_ (it is au tomatically added) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(Autowire dAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBea nFactory.java:1214) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBea nFactory.java:543) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanF actory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-bea ns-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.jav a:230) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans -4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4 .2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java :368) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractA utowireCapableBeanFactory.java:1123) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapa bleBeanFactory.java:1018) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBea nFactory.java:510) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanF actory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-bea ns-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.jav a:230) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans -4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4 .2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1060) ~[sprin g-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.web.filter.DelegatingFilterProxy.initDelegate(DelegatingFilterProxy.java:326) ~[spring-web-4.2.4 .RELEASE.jar:4.2.4.RELEASE] at org.springframework.web.filter.DelegatingFilterProxy.initFilterBean(DelegatingFilterProxy.java:235) ~[spring-web-4.2 .4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.web.filter.GenericFilterBean.init(GenericFilterBean.java:199) ~[spring-web-4.2.4.RELEASE.jar:4.2 .4.RELEASE] at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279) ~[tomcat-embed-core-8. 0.30.jar:8.0.30] at org.apache.catalina.core.ApplicationFilterConfig.(ApplicationFilterConfig.java:109) ~[tomcat-embed-core-8.0.30 .jar:8.0.30] at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4659) [tomcat-embed-core-8.0.30.jar:8.0.30 ] at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5281) [tomcat-embed-core-8.0.30.jar:8.0. 30] at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150) [tomcat-embed-core-8.0.30.jar:8.0.30] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1408) [tomcat-embed-core-8.0.30.jar:8.0.30 ] at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1398) [tomcat-embed-core-8.0.30.jar:8.0.30 ] at java.util.concurrent.FutureTask.run(Unknown Source) [na:1.8.0_66] at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) [na:1.8.0_66] at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [na:1.8.0_66] at java.lang.Thread.run(Unknown Source) [na:1.8.0_66] Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void org.springfra mework.security.config.annotation.web.configuration.WebSecurityConfiguration.setFilterChainProxySecurityConfigurer(org.s pringframework.security.config.annotation.ObjectPostProcessor,java.util.List) throws java.lang.Exception; nested excepti on is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org.spri ngframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfiguration': Injection of aut owired dependencies failed; nested exception is java.lang.IllegalArgumentException: ROLE_USER cannot start with ROLE_ (i t is automatically added) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(Auto wiredAnnotationBeanPostProcessor.java:661) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2. 4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(Autowire dAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] ... 31 common frames omitted Caused by: org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is org .springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfiguration': Injection o f autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: ROLE_USER cannot start with ROL E_ (it is automatically added) at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:1 64) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.evaluateBeanDefinitionString(AbstractBeanFactory.java: 1413) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory. java:1029) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.ja va:1014) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(Auto wiredAnnotationBeanPostProcessor.java:618) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] ... 33 common frames omitted Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfiguration ': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: ROLE_USER cannot start with ROLE_ (it is automatically added) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(Autowire dAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBea nFactory.java:1214) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBea nFactory.java:543) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanF actory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-bea ns-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.jav a:230) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans -4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-4 .2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java: 534) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeansOfType(DefaultListableBeanFactory.java: 523) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.security.config.annotation.web.configuration.AutowiredWebSecurityConfigurersIgnoreParents.getWeb SecurityConfigurers(AutowiredWebSecurityConfigurersIgnoreParents.java:53) ~[spring-security-config-4.0.3.RELEASE.jar:4.0 .3.RELEASE] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66] at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_66] at org.springframework.expression.spel.support.ReflectiveMethodExecutor.execute(ReflectiveMethodExecutor.java:113) ~[sp ring-expression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.MethodReference.getValueInternal(MethodReference.java:129) ~[spring-expressi on-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.MethodReference.access$000(MethodReference.java:49) ~[spring-expression-4.2. 4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.MethodReference$MethodValueRef.getValue(MethodReference.java:347) ~[spring-e xpression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88) ~[spring-exp ression-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120) ~[spring-expression-4.2.4.RELEA SE.jar:4.2.4.RELEASE] at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242) ~[spring-expression-4. 2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.context.expression.StandardBeanExpressionResolver.evaluate(StandardBeanExpressionResolver.java:1 61) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE] ... 37 common frames omitted Caused by: java.lang.IllegalArgumentException: ROLE_USER cannot start with ROLE_ (it is automatically added) at org.springframework.util.Assert.isTrue(Assert.java:68) ~[spring-core-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.security.config.annotation.authentication.configurers.provisioning.UserDetailsManagerConfigurer$ UserDetailsBuilder.roles(UserDetailsManagerConfigurer.java:167) ~[spring-security-config-4.0.3.RELEASE.jar:4.0.3.RELEASE ] at edu.spring.boot.app.security.SecurityConfiguration.configureGlobal(SecurityConfiguration.java:18) ~[classes/:na] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66] at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66] at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66] at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_66] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(Auto wiredAnnotationBeanPostProcessor.java:654) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) ~[spring-beans-4.2. 4.RELEASE.jar:4.2.4.RELEASE] at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(Autowire dAnnotationBeanPostProcessor.java:331) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE] ... 59 common frames omitted 

好的,我找到了安全配置设置的解决方案(不是AuthenticationManager)。

首先,根据Spring Boot dot,我们必须添加@EnableWebSecurity注释。

其次,我们必须在方法的末尾覆盖配置方法WITH @Override注释和super.configure(http)。

所以工作配置代码如下所示:

  @Configuration @EnableWebSecurity //Very important! @EnableGlobalMethodSecurity(securedEnabled = true) @Profile("dev") public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Override //Very important! protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/app/user/*").hasAnyRole("USER", "ADMIN") .antMatchers("/app/posts/*").hasAnyRole("USER", "ADMIN") .antMatchers("/app/*").permitAll() .and() .formLogin() .loginPage("/app/") .loginProcessingUrl("/login") .usernameParameter("username") .defaultSuccessUrl("/app/", true) .and() .logout() .logoutUrl("/app/logout") .and() .csrf() .and() .exceptionHandling() .accessDeniedPage("/app/forbidden"); super.configure(http); //Very important! } } 

现在我的配置正在加载,并且正常运行。

似乎Spring Boot加载了我的自定义Spring Securty配置,但它没有使用它。

您没有正确配置您的AuthenticationManager 。 你应该使用@Autowired

 @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{ auth.inMemoryAuthentication().withUser("user").password("password").roles("USER"); } 

您可以在此处阅读有关Spring安全文档的更多信息 此外,请确保您的配置将通过弹簧启动来获取。 您可以在此处阅读有关Spring boot中的标准项目结构及其安全集成的更多信息 。

更新基于堆栈跟踪:

引起:java.lang.IllegalArgumentException:ROLE_USER无法以ROLE_开头

您应该将ROLE_前缀放在roles("ROLE_USER") ,只需使用roles("USER")

你删除了这段代码吗?

  @Autowired public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception{ auth.inMemoryAuthentication().withUser("user").password("password").roles("USER"); }