Skip to content
Greg Turnquist edited this page Feb 22, 2018 · 26 revisions

Welcome to Learning Spring Boot 2nd Edition’s wiki!

Here is the place where detailed notes are kept to help you get from the book (based on Spring Boot 2.0.0.M5) to the current state of things (Spring Boot 2.0.0.RC1).

Update to Spring Boot 2.0.0.RC1

The code base was initial published against Spring Boot 2.0.0.M5. It was upgraded to 2.0.0.RC1. For the changes to make to your own applications, check out the following sections.

Corresponding Spring portfolio upgrades

  • Spring Cloud - Finchley M6

  • Spring Cloud Stream - Elmhurt M4

Key build changes

  • org.springframework.boot:spring-boot-starter-security-reactiveorg.springframework.boot:spring-boot-starter-security

Code changes

  • In Chapter 10, Take Your App To Production with Spring Boot, Spring Cloud Gateway is introduced. As a lingering side effect of Spring Session being lazy in saving session updates, I wrote a custom Spring Cloud Gateway filter to force the current WebSession (holder of security context) to get saved to MongoDB before making a remote call. The recipient of the remote call uses the SESSION id to then fetch these security context. Since publication, that bit of code was added to Spring Cloud Gateway, making it unnecessary in the book.

  • HttpSecurity is renamed as ServerHttpSecurity.

  • The frontend microservice’s security policy is changed to:

    @EnableWebFluxSecurity
    public class SecurityConfiguration {
    
    	@Bean
    	SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
    		return http
    			.authorizeExchange()
    				.pathMatchers("/**").authenticated()
    				.and()
    			.httpBasic()
    				.securityContextRepository(new WebSessionServerSecurityContextRepository()) // (1)
    				.and()
    			.csrf().disable() // (2)
    			.build();
    	}
    }
    1. You can now specify that all security details are stored in the HTTP session using httpBasic().securityContextRepository(new WebSessionServerSecurityContextRepository()). This also creates new session, replacing the security.session=always attribute.

    2. CSRF, which wasn’t operational at the time of writing, now is, and is on by default. So for now, it’s disabled explicitly via csrf().disable().

  • The backend microservice security policies are configured like this:

    @EnableWebFluxSecurity
    @EnableReactiveMethodSecurity
    public class SecurityConfiguration {
    
    	@Bean
    	SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
    		return http
    			.securityContextRepository(new WebSessionServerSecurityContextRepository()) // (1)
    			.authorizeExchange()
    				.anyExchange().authenticated()
    				.and()
    			.csrf().disable() // (2)
    			.build();
    	}
    }
    1. Setting the securityContextRepository at the top configures is to read from the WebSession, which is fetched from Spring Session MongoDB. This constrains the services to not create a new session, replacing the security.session=never attribute.

    2. This disables CSRF on the backend, since we’re not using in the book.

  • SpringDataUserDetailsRepository, which used to implement UserDetailsRepository now implements ReactiveUserDetailsService.

  • Spring Security now supports multiple password encoders/decoders. Passwords themselves are able to carry a tag (like {sha1}aj320gjr to signal the password was encoded using SHA-1. Faux users are now created like this:

    User.withDefaultPasswordEncoder() // (1)
        .username(user.getUsername()) // (2)
        .password(user.getPassword()) // (3)
        .authorities(user.getRoles()) // (4)
        .build()
    1. Creates a DelegatingPasswordEncoder, which in turn can support a multitude of encoders, including a NoOpPasswordEncoder that doesn’t encrypt the password at all.

    2. Fluent API to set username

    3. Fluent API to set password

    4. Fluent API to set list of GrantedAuthority using an array of string-based roles (replacing the need for AuthorityUtils.createAuthorityList(…​)).

  • Thymeleaf still doesn’t have built in support for Spring Security 5’s Reactive support. However, the location of security context details seems to have moved.

    public boolean expr(String accessExpression) {
    	Map<String, Object> sessionVars = (Map<String, Object>) this.context.getVariable("session"); // (1)
    	SecurityContext securityContext = (SecurityContext) sessionVars.get("SPRING_SECURITY_CONTEXT"); // (2)
    	Authentication authentication = securityContext.getAuthentication(); // (3)
            ....
    1. Look in the current Thymeleaf WebFlux context for the session variable. This will retrieve the map of variables stored in the HTTP session.

    2. Inside the HTTP session, look up the SPRING_SECURITY_CONTEXT variable, which contains current security context details.

    3. From the SecurityContext, extract the Authentication object.

Clone this wiki locally