通过@Profile启用WebSecurityConfigurer不起作用

时间:2014-07-18 14:54:03

标签: java spring spring-mvc spring-security spring-boot

我认为,我有一个非常简单的基本设置,可以通过一些身份验证在本地运行Spring Boot webapp。

我希望当我通过Spring Boot运行此应用程序时,我的自定义安全设置会在我指定local配置文件时覆盖默认行为。

mvn -Dspring.profiles.active="local" spring-boot:run

也许我正在指定profiles.active错误,但是当应用运行时,它仍会吐出生成的密码以供使用,并且似乎不允许任何访问{{1没有说认证的路径。

我也没有看到/login下的有效个人资料,这可能有点说明。

我有一个/env覆盖如此:

WebSecurityConfigurer

我的主@Configuration @EnableWebSecurity @Profile("local") @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests().anyRequest().fullyAuthenticated().and().formLogin().permitAll(); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication().withUser("admin").password("admin").roles("ADMIN", "USER") .and().withUser("user").password("user").roles("USER"); } } 类是您标准的Spring Java风格的基本配置:

@Configuration

3 个答案:

答案 0 :(得分:15)

我想我遇到了同样的问题。我想使用Spring配置文件在none,basic,form等之间进行选择。但是,如果我将@Profile@Configuration@EnableWebMvcSecurity放在public class WebSecurityConfig extends WebSecurityConfigurerAdapter类上,就像他们在示例中所示,基本身份验证在我不想要的时候是活跃的AUTH。 (这是我的Application类上的@SpringBootApplication

我用WebSecurityConfigurerAdapter制作bean而不是@Configurations(代码片段在Groovy中)实现了我想要的目标:

@Configuration
@EnableWebMvcSecurity
class SecurityConfig {
    @Bean
    @Profile('no-auth')
    WebSecurityConfigurerAdapter noAuth() {
        new WebSecurityConfigurerAdapter() {
            @Override
            void configure(HttpSecurity http) throws Exception {
                http.authorizeRequests().anyRequest().permitAll()
            }
        }
    }

    @Bean
    @Profile('default')
    WebSecurityConfigurerAdapter basic() {
        new WebSecurityConfigurerAdapter() {
            @Override
            void configure(HttpSecurity http) throws Exception {
                http
                    .authorizeRequests()
                        .antMatchers('/').permitAll()
                        .anyRequest().authenticated()
                        .and()
                    .httpBasic()
            }

            @Override
            public void configure(AuthenticationManagerBuilder auth) throws Exception {
                auth
                    .inMemoryAuthentication()
                        .withUser("user").password("password").roles("USER");
            }
        }
    }
}

答案 1 :(得分:4)

第二次尝试更好地控制安全设置。什么是控制安全自动配置的高级选项:

  • 完全永久关闭安全性:
    • 从类路径中删除Spring Security
    • 或排除安全自动配置 - @EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
  • 通过设置security.basic.enabled = false
  • 关闭默认的基本身份验证安全性

如果您完全控制安全设置,安全自动配置和弹簧配置文件的使用方式,则可以轻松控制不同的安全设置。

@Configuration
@ComponentScan
public class Application {
    public static void main(String[] args) throws Throwable {
        SpringApplication.run(Application.class, args);
    }
}

@Configuration
public class WebSecurityConfig {

    @Configuration
    @EnableAutoConfiguration(exclude = SecurityAutoConfiguration.class)
    @ConditionalOnExpression("!${my.security.enabled:false}")
    protected static class DefaultWebSecurityConfig {
    }

    @Configuration
    @EnableAutoConfiguration
    @EnableWebMvcSecurity
    @Profile("local")
    @ConditionalOnExpression("${my.security.enabled:false}")
    protected static class LocalWebSecurityConfig extends WebSecurityConfigurerAdapter {
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                .authorizeRequests()
                    .antMatchers("/", "/home").permitAll()
                    .anyRequest().authenticated();
            http
                .formLogin().loginPage("/login").permitAll().and()
                .logout().permitAll();
        }

        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
            auth
                .inMemoryAuthentication()
                    .withUser("user").password("password").roles("USER");
        }
    }

}

在上面的课程中,我基本上从@EnableAutoConfiguration课程顺序中删除了Application,以便有条件地使用它。创建了两个配置类DefaultWebSecurityConfigLocalWebSecurityConfig,这些配置类由my.security.enabled标志使用引导@ConditionalOnExpression选择。

如果我的安全性未启用,则首先配置只会排除SecurityAutoConfiguration。第二个启用安全性并使用local个人资料。通过使用不同的配置文件创建另一个配置,您可以控制不同配置文件发生的情况。然后,您可以选择是否启用安全性以及使用哪个配置文件:

#java -jar build/libs/gs-securing-web-0.1.0.jar
#java -jar build/libs/gs-securing-web-0.1.0.jar --spring.profiles.active=local --my.security.enabled=true

如果您可以选择使用application.yml,则每个配置文件可以自动应用不同的设置,但仍定义默认值。如果您只想禁用默认安全自动配置启用的默认基本身份验证,这将是一件好事。

security:
    basic:
        enabled: false
---
spring:
    profiles: local
security:
    basic:
        enabled: true
---

可能有一百万种不同的方法可以做到这些,并且它始终是个案,最适合当前用例。

答案 2 :(得分:1)

maven将生成一个新进程来运行启动应用程序,它不会继承您传递给mvn命令本身的-Dspring.profiles.active="local"

为什么不构建启动胖jar然后手动将其作为可执行jar运行,然后您可以控制传递给程序的命令行参数。

除此之外,Spring Boot参考文档在安全章节中提及:

  

如果Spring Security位于类路径上,那么默认情况下Web应用程序将在所有HTTP端点上进行“基本”身份验证。

所以我只是用Securing a Web Application Guide尝试了这个,如果我在你的问题中添加了你写的内容,那么在使用非活动的个人资料时,app默认为基本身份验证。

@EnableAutoConfiguration允许您为自动配置类定义排除,但您需要找到一种方法来与配置文件一起禁用它。因此可能将@EnableAutoConfiguration包装在由不同配置文件启用的两个不同@Configuration类中,以便其他类别排除安全性自动配置。

我们在框架本身(以更复杂的方式)做的是使用@Conditional,它提供了启用/禁用部分自动配置的更好方法。