Spring 安全配置@Order 不是唯一异常
Spring Security Configuration @Order not unique exception
我尝试在我的 Spring 安全配置中注册多个过滤器,但我总是遇到相同的异常:
04-Nov-2015 14:35:23.792 WARNING [RMI TCP Connection(3)-127.0.0.1]
org.springframework.web.context.support.AnnotationConfigWebApplicationContext.refresh
Exception encountered during context initialization - cancelling
refresh attempt
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name
'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration':
Injection of autowired dependencies failed; nested exception is
java.lang.IllegalStateException: @Order on WebSecurityConfigurers must
be unique. Order of 100 was already used, so it cannot be used on
com.payment21.webapp.MultiHttpSecurityConfig$ApiWebSecurityConfigurationAdapter$$EnhancerBySpringCGLIB$c79fe4@1d381684
too.
由于我自己的尝试没有奏效,我尝试了 完全相同的代码,如 Spring Security reference:
中所示
@EnableWebSecurity
public class MultiHttpSecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin();
}
}
}
为了找出错误,我尝试用基于 Java 的方法替换 web.xml,但它也没有用。我不知道出了什么问题,是医生错了吗?我的应用程序中的某些东西会扰乱配置吗?系统启动正常,除非我注册第二个 WebSecurityConfigAdapter。
这些是我的依赖项:
compile 'org.springframework:spring-webmvc:4.2.2.RELEASE'
compile 'org.springframework:spring-messaging:4.2.2.RELEASE'
compile 'org.springframework:spring-websocket:4.2.2.RELEASE'
compile 'org.springframework:spring-aop:4.2.2.RELEASE'
compile'javax.servlet:javax.servlet-api:3.0.1'
compile 'org.springframework.security:spring-security-web:4.0.3.RELEASE'
compile 'org.springframework.security:spring-security-config:4.0.3.RELEASE'
您可能在 spring 配置中的某处进行了带有 @order(100)
注释的配置。尝试删除 @order(100)
注释或提供其他订单值。
我发现了错误...从来没有人在片段中发布导入。我们正在使用多模块项目设置,IntelliJ 无法识别 Spring 注释并使用
org.apache.logging.log4j.core.config.Order
而不是
org.springframework.core.annotation.Order
由于 Spring 没有解析正确的注释,它假设两种配置的默认值都是 100。
通常,当同一个bean被解析两次时,就会出现这个异常。
例如,如果 @Configuration
文件导入解析同一个 bean 的 applicationContext.xml,当应用程序启动时尝试注册它(在您的情况下 MultiHttpSecurityConfig
)两次,您会收到此错误。
我解决了从 XML 中删除 bean 定义的错误。
我遇到了同样的问题,我解决了这个错误,将 @Configuration 注释移动到 class 级别。
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
当我将此描述添加到安全配置时,我的问题得到了解决:
@Configuration("MySecurityConfig")
public class MySecurityConfig extends WebSecurityConfigurerAdapter
可能值得注意的是,@Order注解应该在class级别。这有点令人困惑,因为@Journeycorner 配置是一个 multiclass 示例。我的进口示例 :)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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 com.someco.entity.User;
import com.someco.service.SpringDataJpaUserDetailsService;
@Configuration("CustomSecurityConfig")
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(1000)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private SpringDataJpaUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(this.userDetailsService)
.passwordEncoder(User.PASSWORD_ENCODER);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/built/**", "/main.css").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/", true)
.permitAll()
.and()
.httpBasic()
.and()
.csrf().disable()
.logout()
.logoutSuccessUrl("/");
}
}
也许您已经使用 @EnableWebSecurity 注释对另一个 class 进行了注释。请注意,只有一个 class 可以实现此注释。希望对您有所帮助!
也许您已经使用 @EnableWebSecurity 注释对另一个 class 进行了注释。请注意,只有一个 class 可以实现此注释。希望对您有所帮助!
package com.ie.springboot.configuaration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("mkyong").password("123456").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("{noop}123456").roles("ADMIN");
auth.inMemoryAuthentication().withUser("dba").password("123456").roles("DBA");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.antMatchers("/*").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')")
.and().formLogin();
http.csrf().disable();
}
}
我最近遇到了同样的问题,但无法在任何地方找到为我指明正确方向的答案。我最终通过 git 历史追溯我的步骤,发现所做的唯一更改是将 @RefreshScope 注释添加到我的 class.
通过删除 @RefreshScope 注释,我的应用程序运行正常。
将@Order(1000) 放在第二个 WebSecurityConfigurerAdapter 上对我有用
这是因为 Spring 安全性在幕后使用了 WebSecurityConfigurerAdapter 并且此适配器使用的是 order(100),因此 spring 不允许重复的顺序序列。
在我的例子中,我将 @EnableOAuth2Sso
注释放在 @SpringBootApplication
注释的 class 上,但我还有一个单独的 class 扩展 WebSecurityConfigurerAdapter
.正如 @EnableOAuth2Sso
的文档所说:
If there is an existing WebSecurityConfigurerAdapter provided by the user and annotated with @EnableOAuth2Sso, it is enhanced by adding an authentication filter and an authentication entry point. If the user only has @EnableOAuth2Sso but not on a WebSecurityConfigurerAdapter then one is added with all paths secured.
由于添加了默认适配器,我最终添加了两个,这导致了异常。
解决方案当然是将 @EnableOAuth2Sso
注释移动到扩展 WebSecurityConfigurerAdapter
.
的 class
在我的例子中,我有 2 个标签 @EnableWebSecurity
和
@EnableGlobalMethodSecurity(securedEnabled = true)
。当我删除 @EnableWebSecurity
标签时,问题就解决了。
就我而言,在父项目中建立了另一个安全配置 class。我使用 excludeFilters 标签排除父安全配置 class 并添加我的配置 class spring 直接使用该配置 class.
@ComponentScan(basePackages = {
"com.example.parentProject", // this is the package that have securit config staff
},
excludeFilters = {@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
value = {
SecurityConfig.class //which is inhareted from the parent package
})
})
public class SpringApp{
.....
}
我尝试在我的 Spring 安全配置中注册多个过滤器,但我总是遇到相同的异常:
04-Nov-2015 14:35:23.792 WARNING [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.context.support.AnnotationConfigWebApplicationContext.refresh Exception encountered during context initialization - cancelling refresh attempt org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Injection of autowired dependencies failed; nested exception is java.lang.IllegalStateException: @Order on WebSecurityConfigurers must be unique. Order of 100 was already used, so it cannot be used on com.payment21.webapp.MultiHttpSecurityConfig$ApiWebSecurityConfigurationAdapter$$EnhancerBySpringCGLIB$c79fe4@1d381684 too.
由于我自己的尝试没有奏效,我尝试了 完全相同的代码,如 Spring Security reference:
中所示@EnableWebSecurity
public class MultiHttpSecurityConfig {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER").and()
.withUser("admin").password("password").roles("USER", "ADMIN");
}
@Configuration
@Order(1)
public static class ApiWebSecurityConfigurationAdapter extends WebSecurityConfigurerAdapter {
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/api/**")
.authorizeRequests()
.anyRequest().hasRole("ADMIN")
.and()
.httpBasic();
}
}
@Configuration
public static class FormLoginWebSecurityConfigurerAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin();
}
}
}
为了找出错误,我尝试用基于 Java 的方法替换 web.xml,但它也没有用。我不知道出了什么问题,是医生错了吗?我的应用程序中的某些东西会扰乱配置吗?系统启动正常,除非我注册第二个 WebSecurityConfigAdapter。
这些是我的依赖项:
compile 'org.springframework:spring-webmvc:4.2.2.RELEASE'
compile 'org.springframework:spring-messaging:4.2.2.RELEASE'
compile 'org.springframework:spring-websocket:4.2.2.RELEASE'
compile 'org.springframework:spring-aop:4.2.2.RELEASE'
compile'javax.servlet:javax.servlet-api:3.0.1'
compile 'org.springframework.security:spring-security-web:4.0.3.RELEASE'
compile 'org.springframework.security:spring-security-config:4.0.3.RELEASE'
您可能在 spring 配置中的某处进行了带有 @order(100)
注释的配置。尝试删除 @order(100)
注释或提供其他订单值。
我发现了错误...从来没有人在片段中发布导入。我们正在使用多模块项目设置,IntelliJ 无法识别 Spring 注释并使用
org.apache.logging.log4j.core.config.Order
而不是
org.springframework.core.annotation.Order
由于 Spring 没有解析正确的注释,它假设两种配置的默认值都是 100。
通常,当同一个bean被解析两次时,就会出现这个异常。
例如,如果 @Configuration
文件导入解析同一个 bean 的 applicationContext.xml,当应用程序启动时尝试注册它(在您的情况下 MultiHttpSecurityConfig
)两次,您会收到此错误。
我解决了从 XML 中删除 bean 定义的错误。
我遇到了同样的问题,我解决了这个错误,将 @Configuration 注释移动到 class 级别。
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
当我将此描述添加到安全配置时,我的问题得到了解决:
@Configuration("MySecurityConfig")
public class MySecurityConfig extends WebSecurityConfigurerAdapter
可能值得注意的是,@Order注解应该在class级别。这有点令人困惑,因为@Journeycorner 配置是一个 multiclass 示例。我的进口示例 :)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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 com.someco.entity.User;
import com.someco.service.SpringDataJpaUserDetailsService;
@Configuration("CustomSecurityConfig")
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
@Order(1000)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private SpringDataJpaUserDetailsService userDetailsService;
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(this.userDetailsService)
.passwordEncoder(User.PASSWORD_ENCODER);
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/built/**", "/main.css").permitAll()
.anyRequest().authenticated()
.and()
.formLogin()
.defaultSuccessUrl("/", true)
.permitAll()
.and()
.httpBasic()
.and()
.csrf().disable()
.logout()
.logoutSuccessUrl("/");
}
}
也许您已经使用 @EnableWebSecurity 注释对另一个 class 进行了注释。请注意,只有一个 class 可以实现此注释。希望对您有所帮助!
也许您已经使用 @EnableWebSecurity 注释对另一个 class 进行了注释。请注意,只有一个 class 可以实现此注释。希望对您有所帮助!
package com.ie.springboot.configuaration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
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;
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication().withUser("mkyong").password("123456").roles("USER");
auth.inMemoryAuthentication().withUser("admin").password("{noop}123456").roles("ADMIN");
auth.inMemoryAuthentication().withUser("dba").password("123456").roles("DBA");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**").access("hasRole('ROLE_ADMIN')")
.antMatchers("/*").access("hasRole('ROLE_ADMIN') or hasRole('ROLE_DBA')")
.and().formLogin();
http.csrf().disable();
}
}
我最近遇到了同样的问题,但无法在任何地方找到为我指明正确方向的答案。我最终通过 git 历史追溯我的步骤,发现所做的唯一更改是将 @RefreshScope 注释添加到我的 class.
通过删除 @RefreshScope 注释,我的应用程序运行正常。
将@Order(1000) 放在第二个 WebSecurityConfigurerAdapter 上对我有用
这是因为 Spring 安全性在幕后使用了 WebSecurityConfigurerAdapter 并且此适配器使用的是 order(100),因此 spring 不允许重复的顺序序列。
在我的例子中,我将 @EnableOAuth2Sso
注释放在 @SpringBootApplication
注释的 class 上,但我还有一个单独的 class 扩展 WebSecurityConfigurerAdapter
.正如 @EnableOAuth2Sso
的文档所说:
If there is an existing WebSecurityConfigurerAdapter provided by the user and annotated with @EnableOAuth2Sso, it is enhanced by adding an authentication filter and an authentication entry point. If the user only has @EnableOAuth2Sso but not on a WebSecurityConfigurerAdapter then one is added with all paths secured.
由于添加了默认适配器,我最终添加了两个,这导致了异常。
解决方案当然是将 @EnableOAuth2Sso
注释移动到扩展 WebSecurityConfigurerAdapter
.
在我的例子中,我有 2 个标签 @EnableWebSecurity
和
@EnableGlobalMethodSecurity(securedEnabled = true)
。当我删除 @EnableWebSecurity
标签时,问题就解决了。
就我而言,在父项目中建立了另一个安全配置 class。我使用 excludeFilters 标签排除父安全配置 class 并添加我的配置 class spring 直接使用该配置 class.
@ComponentScan(basePackages = {
"com.example.parentProject", // this is the package that have securit config staff
},
excludeFilters = {@ComponentScan.Filter(
type = FilterType.ASSIGNABLE_TYPE,
value = {
SecurityConfig.class //which is inhareted from the parent package
})
})
public class SpringApp{
.....
}