简体   繁体   English

Spring Security 配置 @Order 不是唯一的异常

[英]Spring Security Configuration @Order not unique exception

I've tried to register multiple filters in my Spring Security Configuration, however I always get the same exception:我尝试在 Spring Security 配置中注册多个过滤器,但是我总是遇到相同的异常:

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; 04-Nov-2015 14:35:23.792 警告 [RMI TCP Connection(3)-127.0.0.1] org.springframework.web.context.support.AnnotationConfigWebApplicationContext.refresh 上下文初始化期间遇到异常 - 取消刷新尝试 org.springframework.beans .factory.BeanCreationException:创建名为“org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration”的bean时出错:自动装配依赖项的注入失败; nested exception is java.lang.IllegalStateException: @Order on WebSecurityConfigurers must be unique.嵌套异常是 java.lang.IllegalStateException: WebSecurityConfigurers 上的 @Order 必须是唯一的。 Order of 100 was already used, so it cannot be used on com.payment21.webapp.MultiHttpSecurityConfig$ApiWebSecurityConfigurationAdapter$$EnhancerBySpringCGLIB$$35c79fe4@1d381684 too.已经使用了 100 的顺序,因此它也不能用于 com.payment21.webapp.MultiHttpSecurityConfig$ApiWebSecurityConfigurationAdapter$$EnhancerBySpringCGLIB$$35c79fe4@1d381684。

Since my own attempts didn't work, I tried the exact same code as shown in the Spring Security reference :由于我自己的尝试没有奏效,我尝试了Spring Security 参考中显示的完全相同的代码

@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();
        }
    }
}

To isolate the error I tried to replace the web.xml by a Java based approach, but it didn't work either.为了隔离错误,我尝试用基于 Java 的方法替换 web.xml,但它也不起作用。 I have no idea what's wrong, is the doc wrong?我不知道出了什么问题,是医生错了吗? Can something in my application mess with the configuation?我的应用程序中的某些内容是否会干扰配置? System is starting up properly, unless I register a second WebSecurityConfigAdapter.系统正常启动,除非我注册了第二个 WebSecurityConfigAdapter。

Those are my dependencies:这些是我的依赖项:

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'

Maybe you have annotated another class with the @EnableWebSecurity annotation.也许您已经使用@EnableWebSecurity注释对另一个类进行了注释。 Be aware that only one class can implement this annotation.请注意,只有一个类可以实现此注释。 Hope that will help!希望这会有所帮助!

It may be worth noting, the @Order annotation should be at the class level.可能值得注意的是,@Order 注释应该在类级别。 This is a bit confusing since @Journeycorner configuration is a multiclass example.这有点令人困惑,因为 @Journeycorner 配置是一个多类示例。 My example with imports :)我的导入示例:)

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("/");
}

}

I have found the error... noone ever posts imports in snippets.我发现了错误......没有人在片段中发布导入。 We are using a multi module project setup, and IntelliJ didn't recognise the Spring annotations and used我们正在使用多模块项目设置,并且 IntelliJ 无法识别 Spring 注释并使用

org.apache.logging.log4j.core.config.Order org.apache.logging.log4j.core.config.Order

instead of代替

org.springframework.core.annotation.Order org.springframework.core.annotation.Order

Since Spring didn't parse the correct annotations, it was assuming the default value 100 for both configurations.由于 Spring 没有解析正确的注解,它假设两种配置的默认值都是 100。

Usually, this exception occurs when the same bean is resolved twice.通常,当同一个 bean 被解析两次时会发生此异常。 For example if a @Configuration file imports an applicationContext.xml that resolve the same bean, when the application starts tries to register it (in your case MultiHttpSecurityConfig ) twice, and you get this error.例如,如果@Configuration文件导入解析相同 bean 的 applicationContext.xml,当应用程序启动时尝试注册它(在您的情况下MultiHttpSecurityConfig )两次,并且您会收到此错误。

I resolved the error removing the bean definition from the XML.我解决了从 XML 中删除 bean 定义的错误。

将 @Order(1000) 放在第二个 WebSecurityConfigurerAdapter 上对我有用

Maybe you have annotated another class with the @EnableWebSecurity annotation.也许您已经使用 @EnableWebSecurity 注释对另一个类进行了注释。 Be aware that only one class can implement this annotation.请注意,只有一个类可以实现此注释。 Hope that will help!希望这会有所帮助!

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();

    }
}

My issue got solved when I added this description to the Security Config:当我将此描述添加到安全配置时,我的问题得到了解决:

@Configuration("MySecurityConfig")
public class MySecurityConfig extends WebSecurityConfigurerAdapter

I recently encountered the same issue but wasn't able to find an answer anywhere to point me in the right direction.我最近遇到了同样的问题,但无法在任何地方找到答案来指明正确的方向。 I ended up retracing my steps through git history to find that the only change made was adding @RefreshScope annotation to my class.我最终通过 git 历史回顾了我的步骤,发现所做的唯一更改是将 @RefreshScope 注释添加到我的类中。

By removing the @RefreshScope annotation my application worked.通过删除 @RefreshScope 注释,我的应用程序可以正常工作。

In my case, I had put the @EnableOAuth2Sso annotation on the class annotated with @SpringBootApplication , but I also had a separate class extending WebSecurityConfigurerAdapter .就我而言,我已经把@EnableOAuth2Sso批注与注解类@SpringBootApplication ,但我也有一个单独的类扩展WebSecurityConfigurerAdapter As the documentation of @EnableOAuth2Sso says:正如@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.如果存在由用户提供并使用 @EnableOAuth2Sso 注释的现有 WebSecurityConfigurerAdapter,则通过添加身份验证过滤器和身份验证入口点来增强它。 If the user only has @EnableOAuth2Sso but not on a WebSecurityConfigurerAdapter then one is added with all paths secured.如果用户只有 @EnableOAuth2Sso 而不是在 WebSecurityConfigurerAdapter 上,则添加一个并保护所有路径。

Since a default adapter was being added, I ended up with two, which caused the exception.由于添加了默认适配器,我最终添加了两个,这导致了异常。
The solution was of course to move the @EnableOAuth2Sso annotation to the class which extended WebSecurityConfigurerAdapter .解决方案当然是将@EnableOAuth2Sso注释移动到扩展WebSecurityConfigurerAdapter的类。

In my case, I had 2 tags @EnableWebSecurity and @EnableGlobalMethodSecurity(securedEnabled = true) .就我而言,我有 2 个标签@EnableWebSecurity@EnableGlobalMethodSecurity(securedEnabled = true) When I removed @EnableWebSecurity tag the problem got solved.当我删除@EnableWebSecurity标签时,问题就解决了。

You might be having configuration with @order(100) annotation somewhere in you spring configuration.您可能在 spring 配置中的某处使用@order(100)注释进行配置。 try removing @order(100) annotation or give some other order value.尝试删除@order(100)注释或提供其他一些订单值。

I had the same problem and I resolved this error moving @Configuration annotation to class level.我遇到了同样的问题,我解决了这个错误,将 @Configuration 注释移动到类级别。

@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter { 

这是因为 Spring security 在底层使用WebSecurityConfigurerAdapter并且该适配器使用 order(100),因此 spring 不允许重复的顺序序列。

In my case, there was another security config class that is established in the parent project.就我而言,在父项目中建立了另一个安全配置类。 I used excludeFilters tag to exclude the parent security config class and I add my config class spring directly use that config class.我使用 excludeFilters 标签来排除父安全配置类,并添加我的配置类 spring 直接使用该配置类。

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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM