首页 > 解决方案 > 具有多个身份验证配置文件的 Spring Boot

问题描述

我按照这两篇文章在 Spring Boot 应用程序中实现了多个身份验证配置文件:

最后的SecurityConfiguration类如下所示:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration {

    @Configuration
    @Profile({"qa", "prod"})
    public static class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {
        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .cors()
                    .and()
                    .csrf()
                    .disable()
                    .authorizeRequests()
                    .antMatchers("/someUrl").permitAll()
                    .antMatchers("/someUrl").fullyAuthenticated()
                    .antMatchers("/api/ping").permitAll()
                    .antMatchers("/**").fullyAuthenticated()
                    
                    ...
                    .

        }
    }

    @Configuration
    public static class LocalSecurityConfiguration extends WebSecurityConfigurerAdapter {
...

        @Override
        @Bean
        public AuthenticationManager authenticationManagerBean() throws Exception {
            return super.authenticationManagerBean();
        }

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .cors()
                    .and()
                    .csrf()
                    .disable()
                    .authorizeRequests()
                    .antMatchers("/someUrl").permitAll()
                    .antMatchers("/someUrl").fullyAuthenticated()
                    .antMatchers("/api/ping").permitAll()
                    .antMatchers("/**").permitAll().
                    ...
                    .

        }
    }
}

我也有单独application-{profile}.yaml的文件qaprod配置文件(环境)。

启动应用程序时

mvn spring-boot:run -Dspring.profiles.active=qa

我看到应用了正确的配置文件(qa):

Running with Spring Boot v2.1.3.RELEASE, Spring v5.1.5.RELEASE
...
 The following profiles are active: a
...

但它后来失败了:

***************************
APPLICATION FAILED TO START
***************************

Description:

The bean 'authenticationManagerBean', defined in class path resource [com/.../SecurityConfiguration$WebSecurityConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [com/../SecurityConfiguration$LocalSecurityConfiguration.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

[WARNING] 
java.lang.reflect.InvocationTargetException
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0 (Native Method)
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke (NativeMethodAccessorImpl.java:62)
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke (DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke (Method.java:566)
    at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run (AbstractRunMojo.java:558)
    at java.lang.Thread.run (Thread.java:834)
Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'authenticationManagerBean' defined in class path resource [com/../SecurityConfiguration$WebSecurityConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=securityConfiguration.WebSecurityConfiguration; factoryMethodName=authenticationManagerBean; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/.../SecurityConfiguration$WebSecurityConfiguration.class]] for bean 'authenticationManagerBean': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=securityConfiguration.LocalSecurityConfiguration; factoryMethodName=authenticationManagerBean; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/..../SecurityConfiguration$LocalSecurityConfiguration.class]] bound.

在不指定任何配置文件的情况下运行时,它会毫无错误地启动。那有什么问题?

谢谢你。

标签: spring-bootspring-security

解决方案


据我了解,当您启用qa配置文件时,两个类型的 beanWebSecurityConfiguration都处于活动状态,因此 Spring 无法处理它们同时启用,这就是您遇到错误的原因。当您在没有配置文件的情况下运行它时,则WebSecurityConfiguration不会启用,因此只有一个类型WebSecurityConfigurerAdapter的 bean 处于活动状态。一种解决方案是用否定条件注释 LocalSecurityConfigurationbean,例如

@Profile("!qa & !prod")

这适用于 Spring 版本 > 5.1(Spring Boot 2.1),在以前的版本中,您可以使用 @Conditional 注释(https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework /context/annotation/Conditional.html)并创建一个自定义实现来表达你的逻辑扩展SpringBootCondition


推荐阅读