A quick note on Spring Boot Security

February 14, 2017 by Michael

I just stumbled upon an article that wants to show in great detail how to customize Spring Security inside a Spring Boot application.

It first adds the spring-boot-security-starter through

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-security</artifactId>
</dependency>

Nothing wrong here: Together with @SpringBootApplication the starter configures Spring Security with the filter chain and all auth in the correct places. You dont’t have to add @EnableWebSecurity, in fact: you shouldn’t! It will turn the default auto configuration of your starter of.

Next, the article continuous on how to overwrite the generated user and password: I would go with the security.user.name and security.user.password properties if I wouldn’t have a good reason otherwise.

If I want to add more in-memory users, than I have to do some configuration. But: When extending WebSecurityConfigurerAdapter, just use the methods provided, no need to @EnableWebSecurity if you already have @SpringBootApplication on a class! Also no need to invent custom methods, just use the following:

package de.springbootbuch.actuators;
 
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 
@Configuration
public class SecurityConfig 
		extends WebSecurityConfigurerAdapter {
 
	@Override
	protected void configure(AuthenticationManagerBuilder auth) throws Exception {		
		auth.inMemoryAuthentication().withUser("poef").password("fump").roles("ACTUATOR");
	}
}

If you want to role your own UserDetailsService implementation, it’s even easier:

package de.springbootbuch.actuators;
 
import java.util.Collections;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
 
@Configuration
public class SecurityConfig {
	@Bean
	public UserDetailsService userDetailsService() {
		return (String username) -> {
			if("poef".equals(username))
				return new User("poef", "fump", Collections.EMPTY_LIST);
			else
				throw new UsernameNotFoundException("n/a");
		};
	};	
}

Notice that there’s just one bean of type UserDetailsService.

And finally, if you want to overwrite some settings of Spring Boot Starter Security defaults, it’s the order of WebSecurityConfigurerAdapter that matters.

This one

package de.springbootbuch.actuators;
 
import org.springframework.boot.actuate.autoconfigure.ManagementServerProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
 
@Configuration
@Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfig 
		extends WebSecurityConfigurerAdapter {
 
	@Override
	protected void configure(final HttpSecurity http) 
			throws Exception {
		http
			.httpBasic()
			.and()
			.authorizeRequests()
			.antMatchers("/metrics/counter**")
				.permitAll()
			.antMatchers("/metrics/**")
				.authenticated();
	}
}

together with endpoints.metrics.sensitive = false (needed since Spring Boot 1.5.1 to turn off the handler interceptor that secures Actuator endpoints without even having Security on the class path), it overwrites the settings for the Actuator endpoints, allowing unauthorized access to /metrics/counter but not to the other metrics by putting the configuration at the right place: @Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER).

My tip for Spring Boot and Spring Security: Don’t think too much, don’t try to be smarter than the starter. Don’t turn off the defaults completely if you don’t know what you’re doing. If you extend a WebSecurityConfigurerAdapter, make sure you put it into the right order through @Order and one of those XXX_OVERRIDE_ORDER constants. And also: Use the provided hooks!

The samples here are from my upcoming German Spring Boot Buch, which will be available right in time with Spring Boot 2.0 in autumn.

4 comments

  1. Dhiraj wrote:

    Thanks Michael.I realized that @EnableWebSecurity is not required in my one of my post at http://www.devglan.com/faq/sec.....g-security. I will be removing that instantly. Can you please write another post or provide me any link to explore more on spring boot security for me. Also, I wanted some nice explanation on ACCESS_OVERRIDE_ORDER

    Posted on February 15, 2017 at 8:22 AM | Permalink
  2. Michael wrote:

    Hi,
    thanks for your comment 🙂

    I’d start with the Spring Security Reference (http://docs.spring.io/spring-s.....tmlsingle/), which is quite good.

    The interesting part in this case for you is the Multiple HttpSecurity, basically the point in which you want to insert the your own configuration that should take precedence over the defaults.

    That’s where the ACCESS_OVERRIDE_ORDER constant comes in play. This is a constant from Spring Boot Actuator, that defines in which place you must insert your own config with high precedence.

    Have a nice day,
    Michael.

    Posted on February 15, 2017 at 8:35 AM | Permalink
  3. Alper wrote:

    Trying to figure this out for the last couple days, thank you!

    Posted on February 22, 2017 at 9:01 PM | Permalink
  4. Michael wrote:

    Thanks for your feedback! You’re welcome 🙂

    Posted on February 22, 2017 at 9:02 PM | Permalink
Post a Comment

Your email is never published nor shared. Required fields are marked *