days
-4
-4
hours
0
-6
minutes
-1
-1
seconds
-2
-5
search
Ready for take-off

Spring Boot 2 – an overview: Spring Data and Spring Security 5

Michael Simons
spring boot
© Shutterstock / Alexander Raths

Spring Data and Spring Security are two important modules whose versions are managed by Spring Boot. Consequently, both modules are affected by the update to Spring Boot 2. New applications created directly with Spring Boot 2 usually benefit the most. Applications that are being updated must address these new aspects through active migration.

Michael Simons is a speaker at JAX 2018 and author of the book “Spring Boot – Moderne Softwareentwicklung im Spring Ökosystem“, published by dpunkt.verlag.

1 Spring Data Kay

Spring Data Kay was released in October 2017 and is now part of Spring Boot 2’s Dependency Management. Based on Spring 5, Java 8 and some new features within the Java EE-7 environment, it contains several larger and smaller subjects:

  • A Redesigned Repository API
    • Improved method names and signatures, Java-8 optional
    • A new method of composing repositories
  • Standalone Kotlin support for immutable data classes
  • A way to declare the nullability constraints of an API
  • And, of course, reactive data access to stores that offer a non-blocking API (including Redis, MongoDB, Couchbase and Cassandra)

In the following I will introduce the new API and the reactive data access. The new API will, in some cases, lead to changes in the client code of existing projects. The reactive database’s access of supported stores is one of Spring Data Kays highlights.

1.1 New method names and signatures

Method names or signatures of Spring Data Kay repositories could sometimes lead to ambiguities. This was a driving factor for the interface redesign:

interface CrudRepository<T, ID> extends Repository<T, ID> {
 
    S save(S entity);
 
    Iterable<S> saveAll(Iterable<S> entities)
 
    Optional<T> findById(ID id);
 
    boolean existsById(ID id);
 
    Iterable<T> findAllById(Iterable<ID> ids);
 
    void deleteById(ID id);
 
    void delete(T entity);
 
    void deleteAll(Iterable<? extends T> entities);
}

findOne was replaced by findById, save and delete using an iterable as parameter was replaced by explicit ...all-pendands, and a types id no longer has to be serializable.

The changes to methods and their signatures (optionally<T> instead of a possible null value) are things that must be migrated proactively.

1.2 Composable Repositories

Spring Data repositories can now be formed from different fragments. The restriction to one basic implementation plus an additional one has been removed.

@Entity
public class CustomerEntity extends Person {
}

Regarding the CustomerEntity of Listing 2, a repository can now be compiled to provide CRUD operations as well as independent search and bulk operations. Listing 3 illustrates a declarative interface:

public interface CustomerRepository extends
    CrudRepository<CustomerEntity, Integer>,
    PersonFragment,
    CustomerBulkLoader{
}

These interfaces naturally include basic implementations. Names, for the most part, can be chosen freely, but the implementing class should end in Impl. Listing 4 shows this quite explicitly:

public interface CustomerBulkLoader {
    void loadCustomers(String fileName);
}
 
public class CustomerBulkLoaderImpl implements CustomerBulkLoader {
    @Override
    public void loadCustomers(String fileName) {
        System.out.println("Loading customers from " + fileName);
    }
}

Spring Data Kay no longer interferes with technically driven approaches to an application. The examples above are part of the Spring Boot books database examples.

1.3 Reactive Support

Spring Data Kay supports non-blocking, “reactive” access to a variety of different data stores. These include Redis, MongoDB, Couchbase and Cassandra, but not JPA. The JDBC API is inherently blocking, and work on reactive additions has only begun in recent months.

In order to use reactive data types, for example the implementation of Project Reactor, either a suitable driver must be included as a dependency or, as in Listing 5, a suitable spring boot starter:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>

The repositories can be declared as usual. Listing 6 shows a simple example and usage in a reactive REST controller:

public interface FilmRepository
    extends ReactiveMongoRepository<Film, String> {
}
 
@RestController
public class FilmRestController {
    private final FilmRepository filmRepository;
 
    public FilmRestController(FilmRepository filmRepository) {
        this.filmRepository = filmRepository;
    }
 
    @GetMapping("/api/films")
    public Flux<Film> getAll() {
        return filmRepository
            .findAll(Sort.by("title").ascending());
    }
}

If MongoDB is used as a store, infinite streams are available. These are based on special collections in MongoDB that emit new objects as soon as they are added to the collection. The use of @Tailable is shown in Listing 7:

public interface FilmWatchedEventRepository  extends
    Repository<FilmWatchedEvent, String> {
    @Tailable
    Flux<FilmWatchedEvent> streamAllBy();
}

2 Conclusion

In all probability, Spring Data’s client code will need to be handled after a Spring Boot application upgrade, but the improved API and reactive support for many stores is worth the effort.

3 Spring Security 5

Spring Security and the automatic configuration of Spring Security by Spring Boot via corresponding starters have probably experienced the most profound changes.

3.1.1 Breaking Changes: Less Magic with Spring Boot

The automatic configuration of Spring Security via spring-boot-starter-security has completely been reworked. While the starter in Spring Boot 1.5 made all kinds of assumptions regarding Spring Security’s default configuration, explicit configurations of the application and “built-in” defaults in Spring Boot, a new credo now applies: Spring Boot has no opinion regarding Spring Security; the defaults of Spring Security do apply. This means, for example, that content negotiation influences whether a request is offered basic or form authentication. This change of faith is accompanied by the renunciation of configuration properties regarding the security prefix: Almost all of them have been removed. What remains – under the new spring.security prefix – are properties for configuring an individual user, the order of the security filters and the new OAuth2 support.

By not having a preference, Spring Boot no longer has to attempt to adapt to possibly existing security configurations within the application. Once an application adjusts just one single aspect of the security filter chain, it is immediately responsible for configuring all aspects.

3.1.2 Breaking Changes: A new password storage mechanism

The question whether a password should be hashed or not is hopefully sufficiently answered. Whether a hash is safe or not, however, is a question of constant debate.

A library such as Spring Security can rarely allow deep changes; therefore, it sometimes cannot react quickly enough if, for example, a default hashing algorithm is to be changed. The Spring Security Team has decided on a thorough cleanup in version 5.

In Spring Security 4, a Noop-Password-Encoder was configured by default, now passwords are hashed with BCrypt. And yet, the default encoder is not a BCryptPasswordEncoder, but a DelegatingPasswordEncoder. Delegating password encoders are able to use different other password encoders, i.e. to delegate different formats. This mechanism is accompanied by a new format for storing passwords: {id}encodedPassword. id represents the abbreviation of a password encoder and encodedPassword represents the hash itself. As a result, Spring Security 5 frees itself from the coupling to rigid password formats and is ready for future innovations.

The new password encoder reads and writes these formats and can be configured to handle stored passwords without identifiers using specific encoders.

In addition to these basic changes, old password encoders that were already deprecated in Spring Security 4 have been removed.

An active migration of a Spring Boot 1 application onto Spring Boot 2 and Spring Security 5 is therefore necessary in at least two cases: 1.) The application uses one of the old, now removed password encoders, or 2.) The application does not use an explicit password encoder.

In the first case, a message digest based encoder may help. In the second case, an active migration is strongly recommended, since the application used previously unhashed passwords.

The blogpost Spring Security 5: A new password storage format explains the advantages in detail and shows some possibilities for migration.

3.2 Integration with the reactive stack

One of Spring Securities key elements is the SecurityContextHolder. This class provides central access to the principal authenticated against an application. In the synchronous web stack, where a task was answered by the same thread that accepted it, this could be implemented using a ThreadLocal based solution. Project Reactor – also the technical basis for Reactive Security – offers via Reactor Context an unchangeable memory area, which is bound to the processing chain of a flux or mono.

For an end developer, Reactive Security and Spring Security are nearly identical, both in terms of URL and method security. The Spring Boot Starter spring-boot-starter-security provides all necessary dependencies and configures the reactive part of Spring Security by itself.

Of course, the source of the authenticatable users also had to become reactive. Alongside the well-known UserDetailsService, the ReactiveUserDetailsService was introduced. Listing 8 shows its use.

@Bean
public ReactiveUserDetailsService userDetailsService() {
    return new MapReactiveUserDetailsService(
        User.withUsername("visitor")
            .password("{noop}visitor")
            .roles("USER")
            .build(),
        User.withUsername("film")
            .password("{noop}store")
            .roles("STORE")
            .build()
    );
}

Users with different roles (as defined in Listing 8) can then be applied to URLs, which are configured as in Listing 9:

@Bean
SecurityWebFilterChain springSecurity(
    ServerHttpSecurity http
) {
    return http
        .authorizeExchange()
        .pathMatchers("/api/watchedRightNow")
            .authenticated()
        .pathMatchers("/api/filmWatched")
            .hasRole("STORE")
        .anyExchange().permitAll()
        .and()
        .build();
}

ServerHttpSecurity is new to Spring Security 5 and, along with its old counterpart, HttpSecurity, reflects the dualism of the old servlet specification-based structures and the new, reactive ones. Many of the known security features are already possible to configure for the reactive stack.

Just as normal method security (@PreAuthorize and Co.) is still deliberately configured with @EnableGlobalMethodSecurity in Spring Boot 2, so are reactive methods. @nableReactiveMethodSecurity complements the kit.

4 Conclusion

Spring Security is one of the oldest projects in the Spring ecosystem. Created in 2003 as “Acegi Security”, it has a rich, long-standing history. I think it’s great that the team has the courage to take on such an enormous cleanup. If this library is deliberately updated, it is generally understood that such an update often requires further work. But if the update comes as part of a larger framework, it can be surprising. Nevertheless, in my opinion, the advantages outweigh the disadvantages. The lack of “magic” in the Spring environment may be irritating at first, but for me it shows that the Spring engineering team is well aware of the balance between too little and too much automatic configuration.

In the next part of this series on Spring Boot 2, I present the changes in one of Spring Boots own modules: the Spring Boot Actuator. There are also some surprises there.

Spring Boot – Modern software development within the Spring ecosystem
The Spring Boot book will be published in late April 2018 and will cover all current topics related to Spring Boot 2. In addition to the reactive programming model with Spring 5, this includes the new actuator infrastructure, Micrometer.io support and much more. This book is intended to appeal to interested developers from the Java EE area as well as Spring developers and give them a “recipe” to handle recurring tasks from everyday business life elegantly and without distraction using Spring Boot.

Further information on the book can be found here!

Author
spring boot

Michael Simons

Michael Simons works as a Senior Consultant at innoQ Germany. He is a member of the NetBeans Dream Team and founder of the Euregio JUG. Michael writes on his blog about Java, Spring and software architecture. He is on Twitter as @rotnroll666, where he deals with Java, music and minor and major problems as a husband and father of two children. In January 2018 Michael’s book “Spring Boot — Moderne Softwareentwicklung im Spring-Ökosystem” will be published by dpunkt.verlag. The book can already be pre-ordered at springbootbuch.de. It covers Spring Boot 2 and the new, reactive programming paradigm of Spring 5 as well as Spring basics and thus appeals to experienced Spring developers as well as new beginners. The diagrams in this article are also from the book, as are some of the examples shown. The code is already available on GitHub.


Leave a Reply

3 Comments on "Spring Boot 2 – an overview: Spring Data and Spring Security 5"

avatar
400
  Subscribe  
Notify of
Gar Blomquist
Guest

Will the be an English language edition of the book or only German?

Gabriela Motroc
Admin

We’re not sure what the plans are but we’ll let you know if the English version is happening.

Leeops
Guest

Where can i get the code?