Hands-On Spring Security 5 for Reactive Applications

4.3 (3 reviews total)
By Tomcy John
  • Instant online access to over 8,000+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Overview of Spring 5 and Spring Security 5

About this book

Security is one of the most vital concerns for any organization. The complexity of an application is compounded when you need to integrate security with existing code, new technology, and other frameworks. This book will show you how to effectively write Java code that is robust and easy to maintain.

Hands-On Spring Security 5 for Reactive Applications starts with the essential concepts of reactive programming, Spring Framework, and Spring Security. You will then learn about a variety of authentication mechanisms and how to integrate them easily with the Spring MVC application. You will also understand how to achieve authorization in a Spring WebFlux application using Spring Security.You will be able to explore the security confgurations required to achieve OAuth2 for securing REST APIs and integrate security in microservices and serverless applications. This book will guide you in integrating add-ons that will add value to any Spring Security module.

By the end of the book, you will be proficient at integrating Spring Security in your Java applications

Publication date:
July 2018
Publisher
Packt
Pages
268
ISBN
9781788995979

 

Chapter 1. Overview of Spring 5 and Spring Security 5

This book expects readers to be conversant with Spring Framework (any version) and Spring Security (any version). This is an ice-breaker chapter that introduces the reader to some of the most important concepts; we will expand on them in subsequent chapters.

The chapter will introduce you to new application requirements and then to reactive programming concepts. It touches on application security and how Spring Security addresses security concerns in an application.

We'll continue with Spring Security and then close the chapter by explaining how the examples in this chapter are structured. This is quite important as I expect readers to be comfortable whenever a new concept is introduced in code.

In this chapter, we will cover the following topics:

  • New-generation application requirements
  • Reactive programming
  • Reactive applications
  • Spring Framework
  • Reactive landscape in Java
  • Spring Framework and reactive applications
  • Application security
  • Spring Security
  • Spring Security's core features
  • Spring Security 5's new features
  • The working of Spring Security
  • Core Spring Security modules

 

 

How examples are structured


It's important that you understand how we will be using examples in this book. Since the book tries to give lots of detail on Spring Security 5 and its reactive aspects, we will not have a single use case throughout the book. Instead, we will keep creating small projects to help you understand each of the core concepts covered. Here are some of the important aspects of the code base within this book:

  • Most concepts will be covered using a standalone Spring Boot project.
  • At times, we will use the famous Spring Initializr (https://start.spring.io/) to bootstrap our sample Spring Boot application. In other cases, we will start with a base project that we already have and introduce more concepts through code.
  • Generally, we will be using Java configuration. At times, we might use XML-based configurations.
  • We will keep our examples as simple as possible so that we don't lose focus on the core concept being introduced.
  • Even though this book is focused on reactive applications, we will not be covering this each time it is introduced. At times, we will just be doing plain, old imperative programming as it is more important to know reactive programming and use it when required. It's not that we have to use reactive code everywhere possible, just use it where you see fit.
  • We will be using VS Code for all the projects, and we'll be using the extensions available in VS Code to the fullest. We will also be using the Spring Initializr extension rather than using online Spring Initializr.
  • We will be using Maven most of the time in this book. There might be a case where we try Gradle.
  • Sometimes, we might use IntelliJ IDE and you'll see some screenshots showing this.
  • We'll be using the latest Spring Boot release version, namely 2.0.0. RELEASE. This is the latest release version of Spring Boot at the time of writing this book.
 

New-generation application requirements


Here are some of the core new application requirements:

  • Highly scalable: The social platform has grown exponentially over the last decade and people are more tech-savvy than ever.
  • Resilient, fault-tolerant, and highly available: downtime in your application is something which enterprises are not ready to take in modern times; downtime of even seconds is now creating huge losses for many big businesses.
  • High performance: If your site is slow, people have a tendency to leave and search for alternatives. People have a short attention span and will not stay or come back if your website performs poorly.
  • Hyper-personalization: Users need personalized websites rather than generic websites, and this puts huge pressure on servers to do many intensive analyses in real time.

With technology in everyone's hands (in some form or another, most people use technology), users are quite well-versed in privacy policies and application security. They are aware of most of the security requirements, and companies take time to educate users about the importance of security and the ways they should look for security flaws in applications. You might already know that if a site runs on HTTP as opposed to HTTPS (SSL) and Chrome tags, these sites quite clearly show the users as Not Secure in the address bar. With more people becoming knowledgeable about technology, these aspects are well-known among the majority of users and security has become one of the most talked about subjects in the IT landscape.

Another important aspect is data privacy. Some users are not concerned about sharing their data but some are quite reticent. Many governments recognize this fear and have started making many rules and regulations in this space. One such data privacy rule is the well-known General Data Protection Regulation (GDPR), which has been enforced since May 25th, 2018.

The European Union (EU) GDPR replaces the Data Protection Directive 95/46/EC and was designed to harmonize data privacy laws across Europe, to protect and empower all EU citizen's data privacy and to reshape the way organizations across the region approach data privacy. For more information, you can check this link: https://gdpr-info.eu/art-99-gdpr/.

Modern browsers have also given us enough tools to look at many aspects of a web application in a more detailed manner with regards to security. In addition, browsers have been enhanced with more and more features (for example, a cookie was once one of the options for storing data, but now we have other options, such as localStorage and indexedDB), making it more vulnerable to security breaches and attacks from an ever-open hacker sitting on the sidelines.

 

To achieve these various application requirements, organizations go to public cloud providers instead of their own on-premise datacenters. This puts applications in a more vulnerable state and security aspects come to the forefront. The various components that constitute the application need to be highly secured and nonhackable.

The technological landscape is constantly growing, with new technologies popping up and getting adopted by the developer community. Because of this and the various technology improvements it brings in, many organizations have to adopt these technologies to be compete within the market. This again puts huge pressure on security, as these shiny new technologies may not have concentrated enough effort on making security a major requirement.

All in, having rigid security in an application is a no-brainer requirement and organizations, and end users, are well aware of this fact.

 

Reactive programming


 Over the last few years, JavaScript has become one of the most used languages, and you have already heard of the term reactive in the world of JavaScript, both in a backend and a frontend context.

So, What exactly is reactive programming?—It's a programming paradigm that has asynchronous data streams at its core. The data flows through various parts of the program in the form of a message. The message is produced by a Producer and works in a fire-and-forget manner in which the program produces a message and forgets it. The Subscriber who has subscribed (shown interest) to such messages, gets the message, processes it, and passes on the output as a message for other parts of the program to consume.

In the world of databases, NoSQL presented a huge shift from relational databases. Similarly, this programming paradigm is a huge shift from the conventional programming paradigm (imperative programming). The good thing is that without much knowledge, you have already been coding a bit of reactive code in your day-to-day coding life. Wherever you see the word stream, you are indirectly using a piece of reactive code. Such programming has a name of its own and this aspect has become more mainstream in the industry. Many languages understand the advantages this brings and they have started to natively support this paradigm of programming.

 

 

Reactive applications


In the earlier section of this chapter, we covered how application requirements have drastically changed over the last decade. To cater to this, there is a concept of application development named reactive applications.

It is important to understand the difference between reactive programming and reactive applications. Employing reactive programming doesn't produce reactive applications, but concepts of reactive programming can definitely aid in building reactive applications.

Knowing the Reactive Manifesto will help you understand reactive applications/systems because the manifesto clearly dictates each and every aspect of reactive applications.

Reactive Manifesto

A manifesto is apublicdeclarationofintentions,opinions,objectives,ormotives,asoneissuedbyagovernment,sovereign,ororganization (http://www.dictionary.com/browse/manifesto).

The Reactive Manifesto clearly articulates the views of the issuer, following which an application can be developed to be reactive.

According to the Reactive Manifesto (https://www.reactivemanifesto.org/), a reactive system should be responsive, resilient, elastic, and message-driven.

Let's get into each of these terms in a bit more detail. Most of the text in this section is from the online Reactive Manifesto and then slightly modified to convey the concepts in more easily digestible terms for the readers.

Responsive

In case of problems, responsive systems can quickly detect them and effectively deal with them. These systems also give consistent response times and also establish upper bounds, guaranteeing a minimum Quality of Service (QoS). Because of such characteristics, these systems build end user confidence, simplify error handling, and encourage more interaction from end users.

 

Resilient

In the case of failure, resilient systems stay responsive and interactable. Resilience in an application can be achieved by:

  • Replication: Running the same component in more than one place, so that if one fails, another could handle it and the application can function in a normal fashion.
  • Containment/isolation: Issues of a particular component are contained and isolated within that component and don't interfere with other components or other similar components spun up as part of replication.
  • Delegation: In the case of an issue in a component, without much deliberation, the control is transferred to another similar component that is running in a completely different context.

Elastic

Elastic systems can easily autoscale (increase or decrease resources) as the input rate increases or decreases. Such systems don't have any contention points and can replicate components at will, distributing the increase in load. The way these systems are designed makes sure that when scaling is required, it can be done in a very cost-effective manner by adding on more commodity hardware and software platforms as opposed to expensive hardware and licensed software platforms.

Message-driven

In reactive applications, one of the main aspects is the usage of asynchronous messages to pass data from one component to another. This brings loose coupling between components and aids in achieving location transparency (as long as the component is reachable/discoverable, it can reside in a single node or a cluster of nodes anywhere). Create a message, publish, and forget. Registered subscribers receive the message, process it, and broadcast the message for the other subscribes to do their jobs. This is one of the core aspects of reactive programming and it is one of the fundamental aspects needed for a reactive system. This fire-and-forget concept brings in a non-blocking way of communication, resulting in highly scalable applications.

The following diagram (Figure 1) clearly shows the Reactive Manifesto in a pictorial fashion. It also clearly shows the relationship between the main concepts on the Reactive Manifesto:

Figure 1: Reactive Manifesto

Since reactive applications are responsive, resilient, elastic, and message-driven, these applications are inherently highly flexible, highly scalable, loosely coupled, and fault-tolerant.

Mateusz Gajewski, in one of his presentations shared on www.slideshare.net, sums up the Reactive Manifesto in a very nice way:

Figure 2: Reactive Manifesto as conceived by Mateusz Gajewski

 

 

Spring Framework


Spring Framework is the de facto standard for building Java applications. Over the last decade, it has matured with every major release. Spring Framework 5 became generally available as 5.0.0. in September 2017; this is an important release (major) for the framework since its previous version, which was released in 2013.

One of the major additions to Spring 5 is the introduction of a functional web framework, Spring WebFlux, built on the core reactive foundation. Reactive programming is slowly creeping into the framework and many core modules within the framework are inherently supporting reactive programming in a big way. Since the framework has started supporting reactive programming natively, core aspects of this programming are fully implemented and followed by many of the modules. Also, many reactive concepts have become common language within the framework.

It's important to note that Spring's reactive concepts have been taken as is from Java 8's Reactor Core library, which implements the reactive programming paradigm. Reactor Core is built on top of Reactive Streams Specification, which is the industry standard for building reactive applications in the Java world.

Another important feature is the inclusion of new way by which such applications can be tested. We have a dedicated chapter for Spring WebFlux in (Chapter 5, Integrating with Spring WebFlux) where these aspects will be covered in more detail.

Being a major release, it has loads of stuff either added or enhanced. But we are not going to list all of its features. The full list can be found at this link: https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-Spring-Framework-5.x.

 

Reactive Landscape in Java


It's hard to wrap your head around reactive concepts when you're coming from a traditional programming model. Some of the subsequent sections are aimed at introducing you to reactive concepts and how they evolved into their present state.

 

Reactive Streams and Reactive Streams Specifications

The official document for Reactive Streams (http://www.reactive-streams.org/) says that—Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure. This encompasses efforts aimed at runtime environments (JVM and JavaScript) as well as network protocols.

It started as an initiative between a group of companies in 2013. In April 2015, 1.0 of the specification was released and there were a number of implementations (such as Akka Streams and Vert.x) available at the same time. The specification was initiated with a target to get it included in the official Java standard library and in 2017, with the release of JDK9, it made it's way into it officially. As with any specification, the ultimate aim is to have a number of implementations conforming to the specification, and over time, the specification evolves. The specification consists of some core interfaces, some rules around these, and a Technology Compatibility Kit (TCK).

TCK is a suite of tests that will be executed to check the correctness/compliance of a Java Specification Request (JSR) implementation. In Java Community Process (JCP), TCK is one of the three required components for ratifying a JSR. The other two are JSR specification and JSR reference implementation. The TCK for the Java platform is called Java Compatibility Kit (JCK).

Being a specification, it enables any implementation respecting the specification to cooperate and interoperate with each other. For example, an implementation written in Akka can talk to the Vert.x implementation over the Reactive Streams protocol without any trouble. Adoption is growing and, as we speak, more implementations that conform to the specifications written in different languages are being released:

Figure 3: Reactive Streams Specification/API

The preceding figure clearly shows the Reactive Streams Specification. Some of the important specification rules are as follows:

  • The calls from Publisher to Subscriber and Subscriber to Publisher shouldn't be concurrent in nature.
  • The Subscriber can perform its job synchronously or asynchronously but always has to be non-blocking in nature.
  • From Publisher to Subscriber there should be an upper bound defined. After that defined bound, buffer overflows occur and could result in errors.
  • Apart from NullPointerException (NPE), no other exception can be raised. In the case of NPE, Publisher calls the onError method and Subscriber cancels the Subscription.

In the preceding definition of Reactive Streams, there are some very important terms, namely non-blocking and backpressure, which we'll explore a bit more to understand the core concepts of Reactive Streams.

Non-blocking

Non-blocking means threads never block. If the thread needs to block, the code is written in such a way that the thread gets notified at the right time and the process continues. Reactive programming lets you implement a non-blocking, declarative, and event-driven architecture.

One of the approaches to writing non-blocking applications is by using messages as the means of sending data. A thread sends the request and soon after that, the thread is being used for something else. When the response is ready, it is delivered back using another thread and the requesting party is notified so that further processing can continue:

Figure 4: Non-blocking

 

The non-blocking concept is already implemented by well-known frameworks, such as Node.js and Akka. The approach that Node.js uses is a single thread that sends data in a multiplexing aspect.

In telecommunications and computer networks, multiplexing (sometimes contracted to muxing) is a method by which multiple analog or digital signals are combined into one signal over a shared medium. The aim is to share an expensive resource. For more information about multiplexing, you can visit the following link: http://www.icym.edu.my/v13/about-us/our-news/general/722-multiplexing.html.

Backpressure

In an ideal scenario, every message produced by the Producer is passed to the Subscriber as and when the message is produced without any delay. There is a chance that the Subscriber is unable to handle the messages at the same rate as they are produced and this can cramp its resources.

Backpressure is a method by which the Subscriber can tell the Producer to send messages at a slower rate to give the Subscriber time to handle these messages properly without putting too much pressure on its resources.

Since this is the first chapter, we are just introducing you to these important reactive concepts. Code examples will be covered in subsequent chapters.

Now that we have a brief idea of Reactive Streams and Reactive Streams Specification, we will go into next important reactive concept in Java, namely Reactive Extensions.

Reactive Extensions

Reactive Extensions (Rx or ReactiveX) (https://msdn.microsoft.com) is a library for composing asynchronous and event-based programs using observable sequences and LINQ-style query operators. Data sequences can take many forms, such as a stream of data from a file or web service, web services requests, system notifications, or a series of events such as user inputs.

As stated in the preceding definition, these are APIs that allow stream composition using the Observer pattern. It's my duty to introduce you to the Observer pattern before going any further. The following is the definition of this pattern and it's quite intuitive:

 

The Observer pattern defines a provider (also known as a subject or an observable) and zero, one, or more observers (Subscriber). Observers register with the provider, and whenever a predefined condition, event, or state change occurs, the provider automatically notifies all observers by calling one of their methods. For more information about the Observer pattern, you can refer to this link: https://docs.microsoft.com/en-us/dotnet/standard/events/observer-design-pattern.

Data can flow in a number of forms, such as streams or events. Reactive Extensions lets you convert this dataflow into observables and aids you in programming reactive code.

Rx is implemented in a variety of languages, including Java (RxJava). A full list of implemented languages and more detail on Rx can be found at http://reactivex.io/.

RxJava

RxJava is a Java VM implementation of ReactiveX—a library for composing asynchronous and event-based programs by using observable sequences.

RxJava was ported from .NET to the world of Java by Netflix. After almost two years of development, a stable release of the API was made available in 2014. This stable release targets Java (Version 6 and above), Scala, JRuby, Kotlin, and Clojure.

RxJava is a single-JAR, lightweight library and focuses on Observable abstraction. It facilitates integration with a variety of external libraries, making the library align with reactive principles. Some examples are rxjava-jdbc (database calls using JDBC with RxJava Observables) and Camel RX (Camel support for Reactive Extensions using RxJava).

Reactive Streams and RxJava

RxJava 2.x is a complete rewrite from its predecessor, RxJava 1.x.

RxJava 1.x was created before Reactive Streams Specification, and because of this it doesn't implement it. RxJava 2.x, on the other hand, is written on top of Reactive Streams Specification and fully implements it, and also targets Java 8+. RxJava types in RxJava 1.x have been fully tweaked to comply with the specification and suffered heavy changes when the rewrite took place. It's good to note that there exists a bridge library (https://github.com/ReactiveX/RxJavaReactiveStreams) that bridges between RxJava 1.x types and Reactive Streams, allowing RxJava 1.x to pass the Reactive Streams TCK-compliance tests.

In RxJava 2.x, many concepts remain intact but names have been changed to comply with the spec.

We will not be going deep into RxJava as it is a big topic and there are plenty of books available that dive deep into RxJava.

JDK 9 additions

As part of concurrency updates to JDK 9 (JEP 266), Reactive Streams was added to the Java standard library. Reactive Streams was initiated in 2013 by some of the well-known organizations that wanted to standardize the approach by which asynchronous data can be exchanged between software components. Soon, the concept became adopted by the industry and there evolved a number of implementations that all had similar core concepts but lacked standard nomenclature and terminologies, especially as regards interfaces and package naming. To avoid multiple nomenclatures and to enable interoperability between implementations, JDK 9 included basic interfaces as part of the Flow Concurrency library. This made applications want to implement Reactive Streams to depend on this library but not include specific implementations into the code base. Thus it is very easy to swap between implementations without any trouble.

These interfaces are coded as static interfaces within the java.util.concurrent.Flow class.

Important interfaces

Reactive Streams specifications in Java 9 revolve around just four interfaces—Publisher, Subscriber, Subscription, and Processor. The library also includes a Publisher implementation—SubmissionPublisher. All of these are included within the java.util.concurrent package in the Java standard library. We will touch upon these interfaces in the following subsections.

The Publisher Interface

The definition of this interface is as follows:

public interface Publisher<T> {
  public void subscribe(Subscriber<? super T> s);
}

As you can see, Publisher allows the Subscriber interface to subscribe to it so as to receive the message when Publisher produces it.

The Subscriber Interface

The definition of this interface is as follows:

public interface Subscriber<T> {
  public void onSubscribe(Subscription s);
  public void onNext(T t);
  public void onError(Throwable t);
  public void onComplete();
}

As you can see, the Subscriber interface's onSubscribe method allows Subscriber to be notified when Publisher accepts the Subscription. The onNext method is invoked when new items get published. As the name suggests, the onError method is invoked when there's an error and the onComplete method gets invoked when Publisher has completed its function.

The Subscription interface

The definition of this interface is as follows:

public interface Subscription {
  public void request(long n);
  public void cancel();
}

The method request is for accepting requests for items and method cancel is for when Subscription is cancelled.

The Processor interface

The definition of this interface is as follows:

public interface Processor<T, R> extends Subscriber<T>, Publisher<R> {
}

It inherits from both the Publisher and Subscriber interfaces and therefore inherits all the methods of these interfaces. The main aspect is that the Publisher can produce an item but the Subscriber can consume a different item than that produced by the Publisher.

 

Spring Framework and reactive applications


Spring Framework adopted reactive in 2013 (the same time reactive was born and became more mainstream) with the release of Version 1.0 of Reactor. This was the time when Spring Framework Version 4.0 was released and Spring got itself engaged with Pivotal. In 2016, Spring's 4.3 Version was released with Reactor's Version 3.0. Around this period, the work on Spring's Version 5.0 (major version) was actively under construction.

With new-generation application requirements, many conventional coding practices were challenged. One of the main aspects was to get rid of blocking IO and to find an alternative to conventional imperative programming.

Web applications backed by a Servlet container are inherently blocking, and Spring 5 did a great deal in web application development by introducing a fresh web application framework based on reactive programming: Spring WebFlux.

Spring also has embraced Rx and has used it in many ways within Spring 5. With Spring 5, reactive features are baked into it in many aspects, helping developers to embrace reactive programming easily in a slow-paced manner.

Pivotal is heavily invested in Reactor but has exposed APIs, allowing developers to choose the library of their choice between Reactor and RxJava.

The following diagram depicts Spring 5's reactive programming support:

Figure 5: Spring Framework + Reactor + Rx

Reactor is Pivotal's (SpringSource) answer to implementing Reactive Streams Specification. As mentioned earlier, Spring is heavily invested in Reactor and this section aims to delve a bit deeper into Reactor.

Reactor is a fourth-generation reactive library for building non-blocking applications on the JVM based on the Reactive Streams Specification.

An overview of the history of Project Reactor can be pictorially represented in the following figure:

Figure 6: Project Reactor history

The figure above shows the major releases of Project Reactor. The project kick started in the year 2013 (1.x version) and the major release of 3.x was released in the year 2016. As of writing this book, the core module of the framework is at version 3.1.8.RELEASE.

Now that we have a brief understanding of Spring Framework and its connection with reactive programming, lets dive a bit deep into Project Reactor.

Modules in Reactor

With the latest release of Reactor 3.0 the project has been structured with modularity in mind. Reactor 3.0 consists of four major components namely Core, IO, Addons, and Reactive Streams Commons.

  • Reactor Core (https://github.com/reactor/reactor-core): The main library within Reactor. It provides foundational, non-blocking JVM-compliant Reactive Streams Specification implementations. It also contains code for Reactor types, such as Flux and Mono. 
  • Reactor IO (https://github.com/reactor/reactor-ipc): It contains backpressure-ready components that can be used to encode, decode, send (unicast, multicast, or request/response), and then serve connections. It also contains support for Kafka (https://kafka.apache.org/), Netty (http://netty.io/), and Aeron (https://github.com/real-logic/aeron).
  • Addons (https://github.com/reactor/reactor-addons): As the name suggests, these are add-ons that consist of three components:
    • reactor-adapter: Contains a bridge to RxJava 1 or 2 types, such as Observable, Completable, Single, Maybe, and Mono/Flux back and forth.
    • reactor-logback: Supports logback over asynchronous reactor-core processors.
    • reactor-extra: Contains more operations for Flux, which include mathematical operations such as sum and average.
  • Reactive Streams Commons (https://github.com/reactor/reactive-streams-commons): A collaboration experiment project between Spring's Reactor and RxJava. It also contains Reactor-Streams-compliant operators that both projects implement. Issues fixed on one project are also fixed on the other.

Reactive types in Reactor Core

Reactor provided two reactive types, Flux and Mono, that implement Rx extensively. They can be represented as a timeline in which elements are sequenced according to how they arrived. It is important that you get the hang of these two types. Let's do that in the following subsections.

The Flux reative type

A Reactive Streams publisher with Rx operators that emits 0 to N elements, and then completes (successfully or with an error). For more information, you can check the following link: https://projectreactor.io

Flux<T> is a Publisher<T> with basic flow operations and supports 0..n elements.

The definition of Flux is as follows:

public abstract class Flux<T>
 extends Object
 implements Publisher<T>

 

The following figure, as depicted in the Flux documentation, explains the working of Flux in more detail:

Figure 7: Working of Flux

Flux support is in Spring 5 and a variety of other important modules, including Spring Security. Operators acting on Flux would create new publishers.

Please refer to the Reactor Flux documentation for more information: https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Flux.html.

Now, let's have a look at some code examples where usage of Flux is shown:

  • Creating empty Flux:
Flux<String> emptyFlux = Flux.empty();
  • Creating Flux with items in it:
Flux<String> itemFlux = Flux.just("Spring”, "Security”, "Reactive”);
  • Creating Flux from an existing list:
List<String> existingList = Arrays.asList("Spring”, "Security”, "Reactive”);
Flux<String> listFlux = Flux.fromIterable(existingList);
  • Creating Flux that emits every x milliseconds in an infinite manner:
Flux<Long> timer = Flux.interval(Duration.ofMillis(x));
  • Creating Flux that emits an exception:
Flux.error(new CreatedException());
The Mono reactive type

 

A Reactive Streams Publisher with basic Rx operators that completes successfully by emitting an element, or with an error.

– Mono JavaDoc

Mono<T> is a Publisher<T> that supports 0..1 elements.

The definition of Mono is as follows:

public abstract class Mono<T>
    extends Object
    implements Publisher<T>

As detailed in the documentation, the following figure shows the workings of Mono:

Figure 08: Working of Mono

 

Mono<Void> should be used for a Publisher that completes with no value. The documentation explains each method and how it works using a marble diagram, which is self-explanatory. Again, this type is also supported by Spring 5 and Spring Security.

JavaDoc for Mono contains more information: https://projectreactor.io/docs/core/release/api/reactor/core/publisher/Mono.html.

Let's have a look at some examples:

  • Creating empty Mono:
Mono<String> emptyMono = Mono.empty();
  • Creating Mono with a value in it:
Mono<String> itemMono = Mono.just("Spring Security Reactive”);
  • Creating Mono that emits an exception:
Mono.error(new CreatedException());

Data stream types

Broadly, data streams can be categorized into two types:

  • Cold data streams: There are a number of names by which this is known, such as Cold Source, Cold Observable, and Cold Publisher. These emit data only when one subscribes to it and because of this, all messages produced from start are delivered to the subscriber. If a new Subscriber connects to it, the messages are replayed in ascending order and this is same for any new Subscriber. The Subscriber also has a provision to dictate the rate at which the Publisher should emit messages. These data streams are good candidates for applying reactive backpressure (request(n)), for example, a database cursor or file stream (reading a file).
  • Hot data streams: Again, this has a number of different names, such as Hot Source, Hot Observable, and Hot Publisher. These emit data irrespective of any subscribers connected. When a new Subscriber connects, it just emits the messages from that point in time and cannot replay messages from the start. These cannot pause message emissions, so an alternate mechanism is required to control flow, such as a buffer. Examples of this stream include mouse events and stock prices.

 

It's important to note that operators on a stream can change their property, going from cold to hot and vice versa. Also, there are times when a merge between hot and cold can happen and their properties change.

Reactor and RxJava

One of the main aspects between the two is RxJava 2.x which is Java 6+ compatible, but Reactor is Java 8+ compatible. If you are going with Spring 5, I urge you to use a Reactor. If you are comfortable with RxJava 2.x, there is no need to migrate to Reactor. Reactor is an implementation of the Reactive Streams Specification, so you can remain agnostic of what the underlying implementation is.

Reactive Web Application

Spring 5 has brought reactive concepts into the world of web application development with the inclusion of a number of important components. Let's cover them here.

Spring WebFlux

Spring 5 has a reactive stack baked into it, using which, web applications can be built on top of Reactive Streams capable of running on new non-blocking servers, such as Netty, Undertow, and Servlet containers, running on Servlet specifications greater than 3.1.

Existing web application frameworks, such as Spring MVC, are built for Servlet containers from the outset, but Spring 5 brings with it a new web application framework, Spring WebFlux, created with reactive in mind. We have a dedicated chapter in this book covering Spring WebFlux (Chapter 5, Integrating with Spring WebFlux), so I won't be delving deep into this here. It's good to know that Spring 5 has serious thoughts on reactive and that it is reflected clearly in all these new additions.

Spring WebFlux requires Reactor to be included as one of its core dependencies. But, as always, it does allow you to switch implementations quite easily, if needs be.

Reactive Spring Web

The Spring Web Module (https://github.com/spring-projects/spring-framework/tree/master/spring-web) has many foundational pieces used to build reactive web applications. It allows you to do operations pertaining to the server and the client.

 

The capabilities that it provides on the server are divided into two areas:

  • HTTP: Contained within the org.springframework.http package in spring-web and contains various APIs for HTTP request handling for supported servers
  • Web: Contained within the org.springframework.web package in spring-web and contains various APIs for request processing

This module also contains message codecs that work on the client and aid in encoding and decoding requests and responses. These codecs can also be used on the server.

WebClient

The interface org.springframework.web.reactive.function.client.WebClient is a reactive web client introduced in Spring 5 that can be used to perform web requests. Similarly there is org.springframework.test.web.reactive.server.WebTestClient interface, which is a special WebClient—used to write unit tests within your application. WebClient is the reactive version of RestTemplate, which works over the HTTP/1.1 protocol. They are packaged as part of the spring-webflux module.

WebSockets

The spring-webflux module also has reactive WebSocket implementation. WebSocket allows us to establish a two-way connection between the client and server, and usage of this is becoming more mainstream in new-generation applications.

 

Application security


Application security is composed of various processes put in place to find, fix, and prevent security vulnerabilities in an application.

We are living in the world of Development + Operations (DevOps) where we bring engineering and operational staff together. DevOps advocates automation and monitoring at all levels. With security becoming a very important consideration, a new term, DevSecOps, is becoming prominent—this is where we bring in security as a first-class citizen.

 

For an application, security comes under the nonfunctional requirements. Due to its importance in an application, most organizations have dedicated teams that test applications for potential security flaws. It's a very important aspect to be considered, as in this modern world, a security breach can seriously ruin an organization's brand.

Security is a very broad term and encompasses many aspects. In this book, we will look at some of the fundamental security concerns using the Spring Framework module—Spring Security. After covering some of the core security concerns, we will also look at some of the low-level security problems and how Spring Security can help deal with them.

Since we will be focusing on Spring, we will be delving deep into security concerns with respect to a Java web application development.

 

Spring Security


Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de facto standard for securing Spring-based applications.

– Spring by Pivotal

Spring Security 5 is the new version of the framework and will be the main focus of this book. Spring Security enables you to take care of authentication and authorization of your application in all aspects. It also has top-level projects to deal specifically with a number of authentication mechanisms, such as LDAP, OAuth, and SAML. Spring Security also gives you enough mechanisms to deal with common security attacks, such as Session Fixation, Clickjacking, and Cross-Site Request Forgery. Moreover, it has very good integration with a number of Spring Framework projects, such as Spring MVC, Spring WebFlux, Spring Data, Spring Integration, and Spring Boot.

Spring Security terminologies

It's important to understand some of the most important Spring Security terminologies. Let's look at some of them:

  • Principal: Any user, device, or system (application) that would like to interact with your application.
  • Authentication: A process by which your application makes sure that the principal is who they claim to be.
  • Credentials: When a principal tries to interact with your application, the authentication process kicks in and challenges the principal to pass on some values. One such example is a username/password combination and these values are called credentials. The authentication process validates the principal's passed-in credentials against a data store and replies back with the appropriate result.
  • Authorization: After successful authentication, the principal is checked again for actions that it can perform on your application. This process of checking rights for a principal and then granting necessary permissions is called authorization.
  • Secured item/resource: The item or resource that is marked as secured and requires the principal (user) to successfully complete both authentication and authorization.
  • GrantedAuthority: A Spring Security object (org.springframework.security.core.GrantedAuthority interface) that contains/holds permissions/access-right details of a principal.
  • SecurityContext: A Spring Security object that holds a principal's authentication details.
 

Spring Security's core features


Spring Security provides a number of security features for your application. The two main features for which Spring Security is well-known are it's support for a variety of authentication and authorization methodologies. In this section, we will delve deeply into these core features in more detail.

Authentication

Spring Security provides a number of approaches by which your application can authenticate. It also allows you to write a custom authentication mechanism if these provided default approaches don't fit your requirements. Because of this extensibility, you can even use the legacy application against which authentication can be done. The book has a dedicated chapters (Chapter 3, Authentication Using SAML, LDAP, and OAuth/OIDC and Chapter 4, Authentication Using CAS and JAAS) where we will cover various authentications mechanisms, such as OAuth, LDAP, and SAML, in more detail.

 

Authorization

Spring Security allows you, as an application developer, many choices by which you can authorize user's access to various parts of your application. Here are some of the approaches:

  • Web URL: Based on a URL or URL pattern, you can control access
  • Method invocation: Even a method in a Java Bean can be access-controlled if needs be
  • Domain instance: One of the very cool features is to control access to specific data by having access control of certain needed domain objects within your application
  • Web service: Allows you to secure exposed web services in your application

In the next chapter, we will get into these aspects in a bit more detail with more code snippets.

 

Spring Security 5's new features


Spring Security 5 provides a number of new features along with support for Spring 5. Some of the important new features introduced as part of this release are:

  • Support for OAuth 2.0 and OpenID Connect (OIDC) 1.0: Allows users to log in to your application using their existing OAuth provider (for example, GitHub) or OIDC provider (for example, Google). OAuth is implemented using Authorization Code Flow. We will delve deep into this in subsequent chapters.
  • Reactive support: Spring 5 introduced a new reactive web application framework—Spring WebFlux. Spring Security made sure that this web application framework is fully supported in all aspects (authentication and authorization) using reactive concepts.
  • Improved password encoding: The introduction of the password-encoding delegation allows usage of more than one algorithm for encoding various passwords. The way Spring identifies the algorithm is by reading the prefix of the encoded password, which contains the algorithm used to encode the password. The format is {algorithm}encoded_password.

 

 

Working of Spring Security


In this section, we will look at how Spring Security works. We will first explain the core concepts and then look at various classes the request goes through to perform security.

Servlet Filter

It's quite important to understand Servlet Filter so you can understand Spring Security internals. The following figure clearly explains a Servlet Filter in action. It comes before the request reaches the actual resource and also before the response if sent back to the consumer. It's a pluggable component that can be introduced at any time with configuration in the web configuration file (web.xml).

Figure 9: Working of Servlet Filter

Filter Chain

You can embed any number of Servlet Filters before they reach the actual resource. The filters are fired according to the order in which they are declared in web.xml. This chaining of the Servlet Filter is called Filter Chain. Spring Security works on a number of Servlet Filters arranged as a Filter Chain, each filter performing a single responsibility, then handing it over to the next one, and so on. Most of the built-in filters are good enough for most applications. If needs be, you can write your own filters and place them wherever you want them to be executed.

 

 

Security Interceptor (DelegatingFilterProxy)

When any request reaches an application that is secured using Spring Security, there is a gate the request goes through. This interceptor does all the magic and if things don't look good, it errors out and goes back to the caller, as shown in the following figure:

Figure 10: Working of Security Interceptor

The Security Interceptor makes sure that, according to various security configurations set up for your application, it delegates the work to appropriate parties and makes sure that everyone is happy before actually reaching the resource requested by the caller. To do the actual job, the Security Interceptor employs a number of managers, each entrusted to do a single job. The following figure lists some of the important managers the Security Interceptor works with to perform the function:

Figure 11: Security Interceptor and associated managers

In Spring Security, the Security Interceptor is accomplished by DelegatingFilterProxy. For any request that reaches the web application, this proxy makes sure to delegate the request to Spring Security, and when things go well, it makes sure that the request is taken to the right resource within the web application.

DelegatingFilterProxy is a Servlet Filter that has to be configured in your web.xml file, which then delegates to a Spring-managed bean (@Bean) that implements a ServletFilter interface.

The following code snippet shows how to configure DelegatingProxyFilter in web.xml:

<?xml version="1.0" encoding="UTF-8"?>
 <web-app>
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>
            org.springframework.web.filter.DelegatingFilterProxy
        </filter-class>
    </filter>

    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
 </web-app>

In the preceding code, all the requests to the web application (/* mapping) would go through the DelegatingProxyFilter filter. It's important to note that the name of this filter should be springSecurityFilterChain as Spring Security looks for this default filter name to configure itself. The proxy filter just passes/delegates the control to a bean named springSecuirtyFilterChain. If you are using the default Spring Security setup, the request would then be received by FilterChainProxy. FilterChainProxy is responsible for passing the request through the various Servlet Filters configured as part of Spring Security. The springSecuirtyFilterChain bean need not be explicitly declared, instead, it is taken care of by the framework which is transparent to the developer.

Now that we've looked at all the core concepts of Spring Security, let's come back to the working of Spring Security as pictorially represented in the following diagram. It contains two important security aspects –Authentication and Authorization:

Figure 12: Working of Spring Security

The request from the caller reaches DelegatingFilterProxy, which delegates to FilterChainProxy (Spring Bean), which in turn passes the request through a number of filters, and after successful execution, grants access to the secured resource the caller has asked for.

 

For the complete list of Servlet Filters and their functions, I urge you to go through the Spring Security reference: https://docs.spring.io/spring-security/site/docs/current/reference/html/security-filter-chain.html.

With all these details, the following figure sums up how Spring Security takes care of Authentication and Authorization for your web application:

Figure 13: Authentication and Authorization in Spring Security using a database

When a caller sends a request to a web application protected by Spring Security, it first goes through the Security Interceptor managers, such as Authentication Manager (responsible for authentication) and Access Decision Manager (responsible for authorization), and after executing these successfully, gives the caller access to the secured resource.

For reactive applications, these concepts are all valid. There are equivalent reactive classes and the way we code is the only thing that changes. These are easy to understand and implement.

 

In Chapter 2, Deep Diving into Spring Security, we will cover Authentication, and in Chapter 3, Authentication Using SAML, LDAP, and OAuth/OIDC, we will cover Authorization in detail and delve a bit more deeply into its internals.

 

Core Spring Security modules


In Spring Framework, Spring Security is a top-level project. Within the Spring Security project (https://github.com/spring-projects/spring-security), there are a number of sub-modules:

  • Core (spring-security-core): Spring security's core classes and interfaces on authentication and access control reside here.
  • Remoting (spring-security-remoting): In case you need Spring Remoting, this is the module with the necessary classes.
  • Aspect (spring-security-aspects): Aspect-Oriented Programming (AOP) support within Spring Security.
  • Config (spring-security-config): Provides XML and Java configuration support.
  • Crypto (spring-security-crypto): Contains cryptography support.
  • Data (spring-security-data): Integration with Spring Data.
  • Messaging (spring-security-messaging)
  • OAuth2: Support for OAuth 2.x support within Spring Security:
    • Core (spring-security-oauth2-core)
    • Client (spring-security-oauth2-client)
    • JOSE (spring-security-oauth2-jose)
  • OpenID (spring-security-openid): OpenID web-authentication support.
  • CAS (spring-security-cas): CAS (Central Authentication Service) client integration.
  • TagLib (spring-security-taglibs): Various tag libraries regarding Spring Security.
  • Test (spring-security-test): Testing support.
  • Web (spring-security-web): Contains web security infrastructure code, such as various filters and other Servlet API dependencies.

These are the top-level projects within Spring Framework that are strongly linked to Spring Security:

  • spring-ldap: Simplifying Lightweight Directory Access Protocol (LDAP) programming in Java.
  • spring-security-oauth: Easy programming with OAuth 1.x and OAuth 2.x protocols.
  • spring-security-saml: Bringing the SAML 2.0 service provider capabilities to Spring applications.
  • spring-security-kerberos: Bringing easy integration of Spring application with Kerberos protocol.

Security Assertion Markup Language (SAML) is an XML-based framework for ensuring that transmitted communications are secure. SAML defines mechanisms to exchange authentication, authorization, and non-repudiation information, allowing single sign-on capabilities for Web services.

The Lightweight Directory Access Protocol (LDAP) is a directory service protocol that runs on a layer above the TCP/IP stack. Its based on a client-server model and provides a mechanism used to connect to, search, and modify Internet directories.

Kerberos is a network authentication protocol. It is designed to provide strong authentication for client/server applications by using secret key cryptography. A free implementation of this protocol is available from MIT and it is also available in many commercial products.

Note

For more information about SAML, LDAP, and Kerberos, you can check the following links:

 

 

 

Summary


In this chapter, we introduced you to new application requirements and then moved to some of the core reactive concepts. We looked at the Reactive Manifesto and reactive programming. We then moved our attention to Spring 5 and Spring Security 5, and touched on some of the new features in it, especially regarding reactive programming. We then looked briefly at Spring's reactive programming efforts by introducing you to Project Reactor. After that, we explored Spring Security in a bit more detail to refresh your thoughts on this subject. Finally, we closed this chapter by giving you an idea of how examples would be structured in this book and what coding practices we will be using.

You should now have a good grasp on reactive programming, and on Spring Security and how it works. You should also have a clear understanding of how to go through the rest of the chapters, especially the example code.

About the Author

  • Tomcy John

    Tomcy John lives in Dubai (United Arab Emirates), hailing from Kerala (India), and is an enterprise Java specialist with a degree in Engineering (B Tech) and over 14 years of experience in several industries. He's currently working as principal architect at Emirates Group IT, in their core architecture team. Prior to this, he worked with Oracle Corporation and Ernst & Young. His main specialization is in building enterprise-grade applications and he acts as chief mentor and evangelist to facilitate incorporating new technologies as corporate standards in the organization. Outside of his work, Tomcy works very closely with young developers and engineers as mentors and speaks at various forums as a technical evangelist on many topics ranging from web and middleware all the way to various persistence stores.

    Browse publications by this author

Latest Reviews

(3 reviews total)
Great book, I was looking for a good book in spring security for a long time and I have it now. Thanks Packt!
Very relevant book with up-to-date examples of best practices and security implementation in Spring. Very good content
Pas mal mais pas assez complet je m'attendais à mieux

Recommended For You

Book Title
Unlock this full book with a FREE 10-day trial
Start Free Trial