HZK
HZK

Reputation: 168

Spring security configuration: enable/disable authentication

my question is like this:

I want to disable and enable authentication through configuration in class which extends WebSecurityConfigurerAdapter. I have test which expects that status is unauthroized if there is no login info provided. This is configuration class:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    public static final String USER = "workshop-user";
    public static final String ADMIN = "workshop-admin";

    @Value("${WORKSHOP_USER_PASSWORD:user}")
    private String userPassword;

    @Value("${WORKSHOP_ADMIN_PASSWORD:admin}")
    private String administratorPassword;

    @Value("${features.security.disable}")
    private boolean securityDisable;

    @Bean
    public BCryptPasswordEncoder encoder() {
        return new BCryptPasswordEncoder(9);
    }

    @Override
    @Bean
    public UserDetailsService userDetailsServiceBean() throws Exception {
        return super.userDetailsServiceBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
            .withUser(USER)
            .password(encoder().encode(userPassword))
            .roles("CLIENT_APP")
            .and()
            .withUser(ADMIN)
            .password(encoder().encode(administratorPassword))
            .roles("CLIENT_APP", "ADMINISTRATOR");
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        if(!securityDisable) {
            http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/**/import").hasRole("ADMINISTRATOR")
                .antMatchers("/api-docs/**", "/swagger-resources/**", "/v2/api-docs", "/**/favicon.ico", "/webjars/**", "/api/admin/health").permitAll()
                .anyRequest().permitAll()
                //replace .permitAll() with .authenticated() for authentiaction
                //replace .authenticated() with .permitAll() for disabling security
                .and()
                .csrf().disable()
                .headers().disable()
                .httpBasic();
        }
        else{
            http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/**/import").hasRole("ADMINISTRATOR")
                .antMatchers("/api-docs/**", "/swagger-resources/**", "/v2/api-docs", "/**/favicon.ico", "/webjars/**", "/api/admin/health").permitAll()
                .anyRequest().authenticated()
                //replace .permitAll() with .authenticated() for authentiaction
                //replace .authenticated() with .permitAll() for disabling security
                .and()
                .csrf().disable()
                .headers().disable()
                .httpBasic();
        }
    }

and this is my flag from application.properties

features.security.disable = true

I have tried to find another way to do it through configuration but couldn't come to another answer. The thing is that i know it is very simple becaues of if/else statement. One is authenticated and the other permitAll entries. Do you know is there a way that uses "better aproach" which does not pollute code with duplication like this? I tried to look in documentation and other posts but couldn't find any relevant information for me.

Upvotes: 0

Views: 6143

Answers (1)

Anil
Anil

Reputation: 374

You can create two security configurations

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/**/import").hasRole("ADMINISTRATOR")
                .antMatchers("/api-docs/**", "/swagger-resources/**", "/v2/api-docs", "/**/favicon.ico", "/webjars/**", "/api/admin/health").permitAll()
                .anyRequest().authenticated()
                //replace .permitAll() with .authenticated() for authentiaction
                //replace .authenticated() with .permitAll() for disabling security
                .and()
                .csrf().disable()
                .headers().disable()
                .httpBasic();
    }
}


@Configuration
@Profile("test")
public class SecurityConfigTest extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers(HttpMethod.POST, "/**/import").hasRole("ADMINISTRATOR")
                .antMatchers("/api-docs/**", "/swagger-resources/**", "/v2/api-docs", "/**/favicon.ico", "/webjars/**", "/api/admin/health").permitAll()
                .anyRequest().permitAll()
                //replace .permitAll() with .authenticated() for authentiaction
                //replace .authenticated() with .permitAll() for disabling security
                .and()
                .csrf().disable()
                .headers().disable()
                .httpBasic();
    }
}

Run based on your requirement

-Dspring.profiles.active=prod
-Dspring.profiles.active=test

Upvotes: 2

Related Questions