禁用Spring Boot的预生产环境中的WebSecurity。

huangapple go评论89阅读模式
英文:

Disable WebSecurity for pre-prod environments Spring Boot

问题

@Configuration
@EnableWebSecurity
@Profile("!test")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfig.class);

    @Value("${server.environment}")
    private String environment;

    @Value("${swagger.user}")
    private String swaggerUser;

    @Value("${swagger.password}")
    private String swaggerPass;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        if ("stage".equals(environment) || "prod".equals(environment)) {
            LOGGER.info("Environment: " + environment + " swagger authentication is on");
            http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/v2/api-docs").authenticated()
                .and()
                .httpBasic();
        } else {
            http.csrf().disable();
            LOGGER.info("Environment: " + environment + " swagger authentication is off");
        }
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser(swaggerUser).password("{noop}" + swaggerPass).roles("USER");
    }
}
@Override
protected void configure(HttpSecurity http) throws Exception {
    http.csrf().disable()
        .authorizeRequests()
        .antMatchers("/**").permitAll();
}
英文:

I am trying to use authentication for our swagger on production. That was going great, when i try to access the swagger it requires password and username. I want this functionality only for production env. Not sure how to disable it for different profiles/environments. I tried with if-else based on .yml property but that caused other problems. POST and UPDATE methods started to return 403 Forbidden. Here is sample code:

   @Configuration
@EnableWebSecurity
@Profile("!test")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfig.class);

    @Value("${server.environment}")
    private String environment;

    @Value("${swagger.user}")
    private String swaggerUser;

    @Value("${swagger.password}")
    private String swaggerPass;




    @Override
    protected void configure(HttpSecurity http) throws Exception {
        if("stage".equals(environment) || "prod".equals(environment)){
            LOGGER.info("Environment: " + environment + " swagger authentication is on");
            http.csrf().disable()
                    .authorizeRequests()
                    .antMatchers("/v2/api-docs").authenticated()
                    .and()
                    .httpBasic();
        } else {
            http.csrf().disable();
            LOGGER.info("Environment: " + environment + " swagger authentication is off");
        }

    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
                .inMemoryAuthentication()
                .withUser(swaggerUser).password("{noop}" + swaggerPass).roles("USER");
    }

I have tried to disable the whole WebSecurityConfig bean but that didn work because the dependency is there, and now everytime it asks for Login.

Tried this , didnt work:

@Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable()
                    .authorizeRequests()
                    .antMatchers("/**").permitAll();
        }

答案1

得分: 7

推荐的方法是为生产环境和预发布环境创建另一个类,而不是使用 if-else。您可能需要使用 permitAll() 允许其他端点,或者需要添加基于权限的方法,比如 hasRole()。同时确保您的控制器中没有任何安全注解,比如 @PreAuthorized@Secured 等。

推荐的方法:

用于生产或分阶段环境的安全配置

@Configuration
@EnableWebSecurity
@Profile("prod")
public class WebSecurityProductionConfig extends WebSecurityConfigurerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityProductionConfig.class);

    @Value("${server.environment}")
    private String environment;

    @Value("${swagger.user}")
    private String swaggerUser;

    @Value("${swagger.password}")
    private String swaggerPass;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        LOGGER.info("Environment: " + environment + " swagger authentication is on");

        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/v2/api-docs").authenticated()
            .antMatchers("**/**").permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser(swaggerUser).password("{noop}" + swaggerPass).roles("USER");
    }
}

用于开发和其他环境的安全配置

@Configuration
@EnableWebSecurity
@Profile("!prod")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfig.class);

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        LOGGER.info("Security configuration for the non prod env is loaded");
        http
            .csrf().disable()
            .authorizeRequests().antMatchers("**/**").permitAll();
    }
}

If-Else 方法

@Configuration
@EnableWebSecurity
@Profile("!test")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfig.class);

    @Value("${server.environment}")
    private String environment;

    @Value("${swagger.user}")
    private String swaggerUser;

    @Value("${swagger.password}")
    private String swaggerPass;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();

        if ("stage".equals(environment) || "prod".equals(environment)) {
            LOGGER.info("Environment: " + environment + " swagger authentication is on");
            http
                .authorizeRequests()
                .antMatchers("/v2/api-docs").authenticated();
        } else {
            http.authorizeRequests().antMatchers("**/**").permitAll();
            LOGGER.info("Environment: " + environment + " swagger authentication is off");
        }
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser(swaggerUser).password("{noop}" + swaggerPass).roles("USER");
    }
}
英文:

The recommended approach is to create another class for production and pre-release environments instead of using if-else. You may need to permit the other endpoints using permitAll() or need to add authority based methods such as hasRole(). Also make sure you don't have any security annotation at the controller such as @PreAuthorized, @Secured etc.

Recommended Approach:

Security configurations for prod or staging environment

@Configuration
@EnableWebSecurity
@Profile("prod")
public class WebSecurityProductionConfig extends WebSecurityConfigurerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityProductionConfig.class);

    @Value("${server.environment}")
    private String environment;

    @Value("${swagger.user}")
    private String swaggerUser;

    @Value("${swagger.password}")
    private String swaggerPass;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        LOGGER.info("Environment: " + environment + " swagger authentication is on");

        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/v2/api-docs").authenticated()
            .antMatchers("**/**").permitAll();
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser(swaggerUser).password("{noop}" + swaggerPass).roles("USER");
    }
}

Security configurations for dev and another environment

@Configuration
@EnableWebSecurity
@Profile("!prod")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfig.class);

    @Override
    protected void configure(HttpSecurity http) throws Exception {
    LOGGER.info("Security configuration for the non prod env is loaded");
        http
            .csrf().disable()
            .authorizeRequests().antMatchers("**/**").permitAll();
    }

}

If-Else Approach

@Configuration
@EnableWebSecurity
@Profile("!test")
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    
    private static final Logger LOGGER = LoggerFactory.getLogger(WebSecurityConfig.class);

    @Value("${server.environment}")
    private String environment;

    @Value("${swagger.user}")
    private String swaggerUser;

    @Value("${swagger.password}")
    private String swaggerPass;


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable();
        
        if ("stage".equals(environment) || "prod".equals(environment)) {
            LOGGER.info("Environment: " + environment + " swagger authentication is on");
            http
                .authorizeRequests()
                .antMatchers("/v2/api-docs").authenticated();
        } else {
            http.authorizeRequests().antMatchers("**/**").permitAll();
            LOGGER.info("Environment: " + environment + " swagger authentication is off");
        }
    }

    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser(swaggerUser).password("{noop}" + swaggerPass).roles("USER");
    }
}

答案2

得分: 0

你可以尝试添加另一个 WebSecurityConfig 的实现,该实现将允许无限制访问你的 Swagger 文档,并使用 @ConditionalOnProperty 注解根据应用的 application.yml 文件中的属性来确定使用哪个实现。

英文:

You could try to add another implementation of WebSecurityConfig which will allow free access to your swagger, and use @ConditionalOnProperty to determine which implementation should be used based on a property from your application.yml.

答案3

得分: 0

Your approach from the beginning seems good,

  1. You create a profile called "test" with configuration like this:
    application-test.properties
    spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
  2. Then add a test profile on WebSecurityConfigurerAdapter by adding the @Profile("!test") same as what I see you did
  3. Enjoin with the test profile without security configuration by activating the test profile

java --spring.profiles.active=test -jar yourapp.jar

or

mvn spring-boot:run -Dspring-boot.run.arguments=--spring.profiles.active=test

英文:

Your approach from the beginning seems good,

  1. You create a profile called "test" with configuration like this:
    application-test.properties
    spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
  2. Then add test profile on WebSecurityConfigurerAdapter by adding the @Profile("!test") same as what I see you did
  3. Enjoin with test profile without security configuration by active test profile

java --spring.profiles.active=test -jar yourapp.jar

or

mvn spring-boot:run -Dspring-boot.run.arguments=--spring.profiles.active=test

答案4

得分: 0

如果您只想为生产环境配置安全性,您只需要为生产环境实现WebSecurityConfigurerAdapter。

@Profile("prod")
@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/v2/api-docs").authenticated()
                .and()
                .httpBasic();
    }
}

有关更多信息,请参阅此博客:https://www.baeldung.com/spring-security-disable-profile

英文:

If you only want to config security for prod environment, you only need to implement WebSecurityConfigurerAdapter for prod environment.

<pre><code>

@Profile(&quot;prod&quot;)
@Configuration
public class ApplicationSecurity extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
            http.csrf().disable()
                    .authorizeRequests()
                    .antMatchers(&quot;/v2/api-docs&quot;).authenticated()
                    .and()
                    .httpBasic();
    }
}

</code></pre>

For more information please this blog: https://www.baeldung.com/spring-security-disable-profile

huangapple
  • 本文由 发表于 2020年9月4日 17:25:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/63738423.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定