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{
.....

}