我对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"); } }
我已经用用户名:user声明了用户,并通过了:密码。我还声明,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:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>szczepanski.gerard</groupId> <artifactId>spring-boot-edu-fm</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringBootEduFreemarker</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.3.2.RELEASE</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.scala-lang</groupId> <artifactId>scala-library</artifactId> <version>2.11.0</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
并且在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.<init>(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点,我们必须添加@EnableWebSecurity批注。
第二,我们必须在方法末尾使用@Override批注和super.configure(http)覆盖configure方法。
因此,有效的配置代码如下所示:
@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! } }
现在,我的配置正在加载,并且可以正常工作。