Chapter 17: Implementing security in reactive applications
The introduction explains why reactive programming can help with divisible tasks and why securing reactive applications requires a different Spring Security approach.
After this chapter you will be able to
- Reactive task processing tradeoffs. Explain how dividing a large task into subtasks can let a reactive application process some work simultaneously and return processed data sooner than an imperative approach, while recognizing that reactive programming is not a good fit for every situation.
- Reactive security implementation differences. Explain why security still matters in reactive applications and why Spring Security adapts how previously discussed features are implemented for them.
- Fragmented reactive data processing. Distinguish imperative processing of data supplied all at once from reactive processing of fragments as they arrive.
- Reactive security context limitation. Explain why the imperative thread-based SecurityContext cannot work the same way for reactive requests and which authorization configurations this affects.
- Reactive user details service. Explain how ReactiveUserDetailsService retrieves users and how the example supplies user details for authentication.
- Reactive authentication request flow. Trace the authentication roles of AuthenticationWebFilter and ReactiveAuthenticationManager, including how credential-based authentication uses user details and a password encoder.
- Reactive authentication context access. Describe the two ways the controller can access authentication details and why reactive applications use ReactiveSecurityContextHolder rather than a ThreadLocal-based approach.
- Authorization after reactive authentication. Explain when authorization occurs in a reactive app: after authentication has finished and details of the authenticated request have been stored in the SecurityContext.
- Reactive authorization configuration. Explain why a reactive app declares a SecurityWebFilterChain bean instead of a SecurityFilterChain bean, and describe how ServerHttpSecurity builds it.
- Reactive endpoint authorization rules. Describe how authorizeExchange(), pathMatchers(), and an authorization rule work together, including how the examples treat /hello and /ciao.
- Custom access decisions. Explain when the reactive access() method is useful and describe the inputs and decision it uses in the section’s example.
- Reactive Method Security Configuration. Describe how the example enables reactive method security and restricts the annotated method to an admin.
- Preauthorization Interception And Denial. Trace what happens when an authorized or unauthorized user calls the protected endpoint in the example.
- Reactive resource server configuration. Explain how the example configures authentication in a SecurityWebFilterChain by calling oauth2ResourceServer() and jwt(), with a Customizer specifying how the token signature is validated.
What it builds on
- Using the SecurityContext (chapter 6) · The imperative SecurityContext and its role in holding authentication.
- Understanding the UserDetailsService contract (chapter 3) · The role of UserDetailsService in retrieving user details.
- Understanding the AuthenticationProvider (chapter 6) · The non-reactive authentication architecture used for comparison.
- Using the requestMatchers() method to select endpoints (chapter 8) · Introduces non-reactive request matching, which the section compares with pathMatchers().
- Selecting requests to apply authorization restrictions (chapter 8) · Provides earlier non-reactive endpoint-authorization context that this section compares with access().
- Applying preauthorization rules (chapter 11) · Using @PreAuthorize to apply rules at the method level.
- Configuring JWT validation (chapter 15) · JWT validation by an OAuth 2 resource server
- (chapter intro) (chapter 14) · The authorization server as the source of access tokens
Section by section
Introduction
The introduction explains why reactive programming can help with divisible tasks and why securing reactive applications requires a different Spring Security approach.
- Reactive task processing tradeoffs: Explain how dividing a large task into subtasks can let a reactive application process some work simultaneously and return processed data sooner than an imperative approach, while recognizing that reactive programming is not a good fit for every situation.
Why it matters: This explains the motivation for using a reactive approach without treating it as universally better. - Reactive security implementation differences: Explain why security still matters in reactive applications and why Spring Security adapts how previously discussed features are implemented for them.
Why it matters: It frames reactive security as the same need for protection applied to a differently designed kind of application.
Key terms: reactive programming, imperative approach, subtasks, application-level security, reactive apps, Spring Security
17.1 What are reactive apps?
The section introduces reactive data processing and explains why its execution model affects Spring Security configurations.
- Fragmented reactive data processing: Distinguish imperative processing of data supplied all at once from reactive processing of fragments as they arrive.
Why it matters: This distinction is the starting point for understanding the reactive app used throughout the chapter. - Publishers and Reactor return types: Describe the publisher–subscriber relationship and distinguish when a Reactor endpoint returns Mono or Flux.
Why it matters: These terms explain the return type of the section’s reactive endpoint. - Reactive security context limitation: Explain why the imperative thread-based SecurityContext cannot work the same way for reactive requests and which authorization configurations this affects.
Why it matters: It explains why reactive authorization needs different security support, without assuming the later configuration details. - Reactive user details retrieval: Explain why user details retrieval also needs to support the reactive approach.
Why it matters: Reactive security changes user management as well as authorization.
Key terms: imperative approach, reactive approach, Publisher, Subscriber, Project Reactor, Mono, Flux, SecurityContext, ThreadLocal, Authentication
17.2 User management in reactive apps
This section shows how reactive Spring Security retrieves users, authenticates requests, and makes authentication details available to application code.
- Reactive user details service: Explain how ReactiveUserDetailsService retrieves users and how the example supplies user details for authentication.
Why it matters: It identifies what changes when familiar username-and-password user management is used in a reactive app. - Reactive authentication request flow: Trace the authentication roles of AuthenticationWebFilter and ReactiveAuthenticationManager, including how credential-based authentication uses user details and a password encoder.
Why it matters: It shows where authentication happens in the reactive architecture and where custom authentication logic would go. - Reactive authentication context access: Describe the two ways the controller can access authentication details and why reactive applications use ReactiveSecurityContextHolder rather than a ThreadLocal-based approach.
Why it matters: It connects successful reactive authentication to the details application code can use.
Key terms: ReactiveUserDetailsService, Mono<UserDetails>, MapReactiveUserDetailsService, PasswordEncoder, AuthenticationWebFilter, ReactiveAuthenticationManager, Mono<Authentication>, ReactiveSecurityContextHolder, SecurityContext, ThreadLocal
17.3 Configuring authorization rules in reactive apps
The section places authorization after authentication in a reactive app and introduces the need to configure authorization rules.
- Authorization after reactive authentication: Explain when authorization occurs in a reactive app: after authentication has finished and details of the authenticated request have been stored in the SecurityContext.
Why it matters: This sequence explains where authorization rules fit in a reactive app’s security flow.
Key terms: authentication, authorization, SecurityContext
17.3.1 Applying authorization at the endpoint layer in reactive apps
This section shows how to configure endpoint authorization in reactive Spring Security apps, including standard rules, custom access decisions, and the components that enforce them.
- Reactive authorization configuration: Explain why a reactive app declares a SecurityWebFilterChain bean instead of a SecurityFilterChain bean, and describe how ServerHttpSecurity builds it.
Why it matters: Using the reactive chain is necessary for these endpoint rules to become part of the app’s security configuration. - Reactive endpoint authorization rules: Describe how authorizeExchange(), pathMatchers(), and an authorization rule work together, including how the examples treat /hello and /ciao.
Why it matters: This is how the app gives different endpoints different access requirements. - Custom access decisions: Explain when the reactive access() method is useful and describe the inputs and decision it uses in the section’s example.
Why it matters: Custom decisions can combine conditions that the simpler authorization methods do not express. - Reactive authorization delegation: Trace the authorization responsibility after authentication from AuthorizationWebFilter to a ReactiveAuthorizationManager.
Why it matters: It connects the rules declared in the security-chain bean to the component that authorizes a request.
Key terms: SecurityWebFilterChain, SecurityFilterChain, ServerHttpSecurity, build(), authorizeExchange(), pathMatchers(), authenticated(), permitAll(), anyExchange(), access()
17.3.2 Using method security in reactive apps
This section shows how to enable reactive method security, apply a role-based rule with @PreAuthorize, and understand why a request that fails the rule is denied.
- Method Level Authorization Flexibility: Explain why reactive method security is useful beyond endpoint authorization and where its rules can be placed.
Why it matters: A rule on a component method can protect a call even when that method is not an endpoint. - Reactive Method Security Configuration: Describe how the example enables reactive method security and restricts the annotated method to an admin.
Why it matters: The enabling annotation and the method annotation serve different purposes: turning on the feature and stating the rule. - Preauthorization Interception And Denial: Trace what happens when an authorized or unauthorized user calls the protected endpoint in the example.
Why it matters: This connects the method's rule to both the blocked method call and the response the caller sees.
Key terms: reactive method security, method level, endpoint layer, @EnableReactiveMethodSecurity, @PreAuthorize, SpEL, aspect, preauthorization rules, HTTP 403 Forbidden
17.4 Creating a reactive OAuth 2 resource server
This section configures a reactive OAuth 2 resource server to validate JWT access tokens and shows how to call an endpoint with a token from an authorization server.
- Reactive resource server configuration: Explain how the example configures authentication in a SecurityWebFilterChain by calling oauth2ResourceServer() and jwt(), with a Customizer specifying how the token signature is validated.
Why it matters: These settings connect reactive web security to the OAuth 2 access-token validation used by the example. - JWT verification key options: Distinguish configuring the URI where the authorization server exposes its public key from providing a public key directly for token signature validation.
Why it matters: The resource server needs a configured public key source to validate token signatures. - Access token endpoint check: Describe the example’s check: generate an access token using the authorization server, then use that token to call the reactive application’s /hello endpoint.
Why it matters: This connects the authorization server’s token to a request handled by the reactive resource server.
Key terms: SecurityWebFilterChain, oauth2ResourceServer(), jwt(), Customizer, public key, token signature validation, publicKey(), jwtSpec, access token, authorization server
17.5 Summary
Concepts explained in this chapter
- MonoMono is a Reactor type representing an asynchronous computation that emits zero or one item.
- reactive applicationA reactive application is an application designed around asynchronous, nonblocking processing of streams of data and events.
- SecurityWebFilterChainSecurityWebFilterChain is a Spring Security interface representing an ordered chain of reactive web security filters that processes server exchanges.
- reactive programmingReactive programming is a programming paradigm based on asynchronous processing of streams of data and events, typically to support nonblocking and concurrent execution.
- ServerHttpSecurityServerHttpSecurity is a Spring Security reactive configuration builder for defining web authentication, authorization, and protection settings.
- authorizeExchange()authorizeExchange() is a ServerHttpSecurity configuration method for defining authorization rules for reactive server exchanges.
- AuthorizationContextAuthorizationContext is a reactive Spring Security object that provides information about the server exchange being authorized.
- AuthorizationDecisionAuthorizationDecision is a Spring Security result object that indicates whether an authorization request is permitted.
- endpoint authorizationEndpoint authorization is authorization enforcement applied by matching incoming requests at web application endpoints.
- pathMatchers()pathMatchers() is a reactive authorization configuration method that matches server exchanges according to request paths and related attributes.
- FluxFlux is a Project Reactor publisher that emits zero or more values asynchronously.
- Project ReactorProject Reactor is a Java library that provides reactive programming types and operators for composing asynchronous streams.
- imperative approachAn imperative approach processes a bulk of available data as a whole rather than incrementally as data arrives.
- reactive streamThe Reactive Streams specification defines standard contracts for asynchronous stream processing with bounded resource usage.
- ReactiveUserDetailsServiceReactiveUserDetailsService is a Spring Security contract that retrieves user details asynchronously for authentication in a reactive application.
- MapReactiveUserDetailsServiceMapReactiveUserDetailsService is a Spring Security ReactiveUserDetailsService implementation that stores user details in memory.
- ReactiveSecurityContextHolderReactiveSecurityContextHolder is the Spring Security holder that provides access to the security context through reactive execution context rather than thread-local storage.
- authentication managerReactiveAuthenticationManager is a Spring Security contract that performs authentication asynchronously in a reactive application.
- oauth2ResourceServeroauth2ResourceServer is a Spring Security configuration method for enabling and configuring OAuth 2 resource-server authentication.
- resource serverA resource server is an OAuth server that hosts protected resources and accepts valid access tokens for authorized requests.
- Spring SecuritySpring Security is an open-source framework for securing Spring applications through authentication, authorization, access control, and protection against common attacks.
- authorizationAuthorization is the process of determining whether an authenticated entity has permission to perform an action or access a resource.
- method-level securityGlobal method security is a method-authorization capability that applies authorization rules across application methods.
These guides are generated from the text of Manning books by Manning's knowledge graph and link to the sections they draw on. The full books are available on liveBook and at manning.com.
