Reactive

Spring Security 5

Workshop

https://andifalk.github.io/reactive-spring-security-5-workshop

Andreas Falk

Novatec Consulting GmbH

https://www.novatec-gmbh.de
andreas.falk@novatec-gmbh.de / @andifalk

Our Security Offerings

  • Security Awareness Trainings
  • Threat Modeling Trainings & Consulting
  • OAuth 2.0 & OpenID Connect 1.0 Trainings & Consulting
  • Spring Security Trainings
  • Security Audits

https://www.novatec-gmbh.de/beratung/

The

Reactive Spring Security Workshop

https://andifalk.github.io/reactive-spring-security-5-workshop https://github.com/andifalk/reactive-spring-security-5-workshop

Part 1

  1. Introduction to Reactive Programming
  2. Spring Security Basics
  3. Spring Security Practice (Hands-On) Part 1
    • Authentication
    • Password Security & Upgrades
  4. Lunch-Break

Part 2

  1. Spring Security Practice (Hands-On) Part 2
    • Authorization
    • Automated Security Tests
  2. Introduction into OAuth 2.0 and OpenID Connect
  3. Spring Security OAuth2/OIDC (Hands-On)
    • Resource Server
    • OIDC Client

In the meantime...

Prepare for the hands-on parts:

https://github.com/andifalk/reactive-spring-security-5-workshop/tree/master/setup

Reactive Systems

reactivemanifesto.org

Reactive Systems

“[...] we want systems that are Responsive, Resilient, Elastic and Message Driven. We call these Reactive Systems.”

reactivemanifesto.org

Reactive Systems

- Responsive -

“The system responds in a timely manner if at all possible”

Reactive Systems

- Resilient -

“The system stays responsive in the face of failure”

Reactive Systems

- Elastic -

“The system stays responsive under varying workload”

Reactive Systems

- Message Driven -

“Reactive Systems rely on asynchronous message-passing”

Reactive Streams

“Reactive Streams is an initiative to provide a standard for asynchronous stream processing with non-blocking back pressure..”

reactive-streams.org/

Reactive Streams

Implementations

Publisher


                            package org.reactivestreams;

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

Subscriber


                            package org.reactivestreams;

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

                        

Subscription


                            package org.reactivestreams;

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

Processor


                            package org.reactivestreams;

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

Reactive Streams

Included Since Java 9

java.util.concurrent.Flow.Publisher<T>

java.util.concurrent.Flow.Subscriber<T>

java.util.concurrent.Flow.Subscription

java.util.concurrent.Flow.Processor<T, R>

Project Reactor

projectreactor.io

Project Reactor

“Reactor is a fourth-generation1 reactive library for building non-blocking applications on the JVM based on the Reactive Streams Specification”

projectreactor.io

1) David Karnok’s Generations of Reactive classification

Composable reactive types

- Mono -

An Asynchronous 0-1 Result

Composable reactive types

- Flux -

An Asynchronous Sequence of 0-N Items

Imperative vs. Reactive

Imperative


                            String msg = "World";
                            String upperCaseMsg = msg.toUpperCase();
                            String greeting = "Hello " + upperCaseMsg + "!";
                            System.out.println(greeting);
                        

Reactive


                            Mono.just("World")
                                .map(String::toUpperCase)
                                .map(um -> "Hello " + um + "!")
                                .subscribe(System.out::println);
                        

Reactor Debug agent

Debugging Reactive code can sometimes be challenging

spring.io/blog/2019/03/28/reactor-debugging-experience

https://projectreactor.io/docs/core/release/reference/#debugging

BlockHound

Detect blocking code

spring.io/blog/2019/03/28/reactor-debugging-experience

https://github.com/reactor/BlockHound

Let's try this...

intro-labs/reactive-playground

 

projectreactor.io/docs/core/release/reference

projectreactor.io/docs/core/release/reference/#which-operator

Spring WebFlux

spring.io/projects/spring-framework

Servlet vs. Reactive Web Stack

Web Threading Model

Reactive Data Stores

Reactive Relational Database Connectivity (R2DBC)

  • Reactive programming APIs for relational databases
  • JDBC: Blocking - R2DBC: Non-blocking reactive API
  • R2DBC drivers available for:
    • Google Cloud Spanner
    • MySQL, MariaDB, PostgreSQL, H2
    • Microsoft SQL Server

https://r2dbc.io

Reactive Spring Book

(Josh Long)

https://leanpub.com/reactive-spring

Security ?

“From my experience all software developers are now security engineers wether they know it, admit to it or do it [...]”

Jim Manico on Twitter

“If it's not secure, it's not guaranteed to be anything else either”

maslow

https://gojko.net/2012/05/08/redefining-software-quality/

OWASP Top 10 2017

owasp top 10

https://www.owasp.org/index.php/Top_10-2017_Top_10

Application Security Verification Standard

https://github.com/OWASP/ASVS

Spring Security Basics

spring.io/projects/spring-security

Spring Security Overview

Spring Security 5

  • Authentication & Authorization
  • Password Encoding & Crypto (BCrypt, Argon2, ...)
  • Support for Servlet & Reactive Web Applications
  • Support for OAuth 2.0 & OpenID Connect 1.0
  • Authz Code (+ PKCE) & Client Credentials
  • Supports JWT and Opaque Tokens
  • Testing Support for Authentication/Authz/JWT

Spring Security 5

Secure By Default

  • Authentication required for all HTTP endpoints
  • Default Validation for JWT
  • Signature, Issuer, Expiration
  • Includes Actuator (Monitoring) Endpoints
  • Except “health” and “info”
  • Session Fixation Protection
  • Session Cookie (HttpOnly, Secure)
  • CSRF Protection
  • Security Response Headers

Spring Security

 

Servlet Web Stack

Security Dependencies

Servlet Web Stack


                            ...
                            implementation
                              'org.springframework.boot:spring-boot-starter-security'
                            implementation
                              'org.springframework.boot:spring-boot-starter-web'
                            ...
                        

Configuration

Servlet Web Stack


                            @Configuration
                            public class WebSecurityConfiguration
                                extends WebSecurityConfigurerAdapter {

                              @Override
                              protected void configure(HttpSecurity http)
                                                   throws Exception {
                                http.authorizeRequests()
                                        .anyRequest()
                                        .authenticated()
                                        .and()
                                        .httpBasic().and().formLogin();
                              }
                            }
                        

Authentication - Servlet Web Stack

Spring Security

 

Reactive Web Stack

Security Dependencies

Reactive Web Stack


                            ...
                            implementation
                              'org.springframework.boot:spring-boot-starter-security'
                            implementation
                              'org.springframework.boot:spring-boot-starter-webflux'
                            ...
                        

Configuration

Reactive Web Stack


                            @Configuration
                            @EnableWebFluxSecurity
                            public class ReactiveWebSecurityConfiguration {

                              @Bean
                              SecurityWebFilterChain
                                    securityWebFilterChain(ServerHttpSecurity http) {
                                return http.authorizeExchange()
                                        .anyExchange()
                                        .authenticated()
                                        .and()
                                        .httpBasic().and().formLogin().and().build();
                              }
                            }
                        

Authentication - Reactive Web Stack

Spring Security

Hands-On

Hands-On application

An online book library

  • Administer books
  • List available books
  • Borrow an available book
  • Return a borrowed book
  • Administer library users

Library Service

Library Service Architecture

Library Service API Docs

https://andifalk.github.io/reactive-spring-security-5-workshop/api-doc.html

Workshop Steps

  • Lab 1: Authentication (Auto Configuration)
  • Lab 2: Customized Authentication
  • Lab 3: Authorization
  • Lab 4: Automated Security Tests

Lab 1: Authentication

(Auto Configuration)

Online Tutorial: Lab 1

Lab 2: Authentication

(Customized)

Online Tutorial: Lab 2

Lab 3: Authorization

Online Tutorial: Lab 3

Lab 4: Automated Security Tests

Online Tutorial: Lab 4

Let's start...

Requirements

Internet Access

Java JDK version 8 or 11

A Java IDE (Eclipse, STS, IntelliJ, VS Code, NetBeans, ...)

Workshop Code

Get via git clone or download as zip file:

https://github.com/andifalk/reactive-spring-security-5-workshop

Workshop Tutorial

https://andifalk.github.io/reactive-spring-security-5-workshop/workshop-tutorial.html

https://github.com/andifalk/reactive-spring-security-5-workshop/raw/master/docs/workshop-tutorial.pdf

Part 2

  1. Introduction into OAuth 2
  2. Introduction into OpenID Connect
  3. Spring Security OAuth2/OIDC (Hands-On)
    • Authorization Code Flow Demo
    • Resource Server
    • OIDC Client

In the meantime...

 

Make sure your Keycloak instance is set up and running

OAuth 2.0

101

RFC 6749: The OAuth 2.0 Authorization Framework
RFC 6750: OAuth 2.0 Bearer Token Usage
RFC 6819: OAuth 2.0 Threat Model and Security Considerations

What is OAuth 2.0?

OAuth 2.0 is an authorization delegation framework

OAuth 2.0 Model

OAuth 2.0 Grant Flows

Client Type Flow Refresh Tokens
Confidential Authorization Code X
Public (Native) Authorization Code (PKCE) X
Public (SPA) Implicit --
Trusted RO Password Creds X
No Resource Owner Client Credentials --

Authorization Code Grant Flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

Authorization code grant flow

We'll see

Authorization Code Grant Flow

in action as part of Intro Lab

Implicit Flow Attacks


Source: Torsten Lodderstedt and Daniel Fett

OAuth 2.0 Security Best Current Practice

“OAuth 2.1” Grant Flows

Client Type Flow Refresh Tokens
Confidential Authorization Code (PKCE) X
Public (Native) Authorization Code (PKCE) X
Public (SPA) Authorization Code (PKCE) --
Trusted RO Password Creds X
No Resource Owner Client Credentials --

Proof Key for Code Exchange by OAuth Public Clients (PKCE)

(“Pixy”)

Mitigates authorization code attacks

Mitigates token leakage in SPAs

Proof Key for Code Exchange by OAuth Public Clients

PKCE - Authorization Request

GET https://authserver.example.com/authorize

?response_type=code

&client_id=abcdefg

&redirect_uri=https://client.abc.com/callback

&scope=api.read api.write

&state=xyz

&code_challenge=xyz...

&code_challenge_method=S256

PKCE - Token Request

POST https://authserver.example.com/token

Content-Type:
application/x-www-form-urlencoded

grant_type=authorization_code&code=ab23bhW56Xb

&redirect_uri=https://client.abc.com/callback

&client_id=123&client_secret=456

&code_verifier=4gth4jn78k_8

OpenID Connect 1.0

101

OpenID Connect Core 1.0
OpenID Connect Dynamic Client Registration 1.0
OpenID Connect Discovery 1.0

OpenID Connect 1.0 is for Authentication

OAuth 2.0 is not an authentication protocol

OIDC additions to OAuth 2.0

  • ID Token
  • User Info Endpoint
  • OpenID Provider Discovery

ID Token

JSON Web token (JWT)

Base 64 Encoded JSON Formatted Value of...

...Header

...Payload

...Signature


                            GET / HTTP/1.1
                            Host: localhost:8080
                            Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1N...
                        

JSON Web Token (JWT)

Header


                            {
                              typ: "JWT",
                              alg: "RS256"
                            }
                        

Payload


                            {
                              iss: "https://identity.example.com",
                              aud: "my-client-id",
                              exp: 1495782385,
                              nonce: "N0.46824857243233511495739124749",
                              iat: 1495739185,
                              at_hash: "hC1NDSB8WZ9SnjXTid175A",
                              sub: "mysubject",
                              auth_time: 1495739185,
                              email: "test@gmail.com"
                            }
                        

ID Token Claims

Scope Required Description
iss X Issuer Identifier
sub X Subject Identifier
aud X Audience(s) of this ID Token
exp X Expiration time
iat X Time at which the JWT was issued
auth_time (X) Time of End-User authentication
nonce -- Associate a client with an ID Token

Access Tokens in OIDC

Format and content still not standardized

But...

OAuth 2 Access Token JWT Profile

Required claims: iss, exp, aud, sub, client_id

Consider privacy restrictions for identity claims

Authorization claims according to SCIM Core (RFC7643):

  • Groups
  • Entitlements
  • Roles

System for Cross-domain Identity Management (SCIM)
JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens

Token Validation

User Info Endpoint


                            GET /userinfo HTTP/1.1
                            Host: identityserver.example.com
                            Authorization: Bearer SlAV32hkKG
                        

                            HTTP/1.1 200 OK
                            Content-Type: application/json

                            {
                             "sub": "248289761001",
                             "name": "Jane Doe",
                             "given_name": "Jane",
                             "family_name": "Doe",
                             "preferred_username": "j.doe",
                             "email": "janedoe@example.com",
                             "picture": "http://example.com/janedoe/me.jpg"
                            }
                        

OpenID Connect 1.0 Configuration

https://idp.example.com/.well-known/openid-configuration


                            {
                              "authorization_endpoint": "https://idp.example.com/auth",
                              "grant_types_supported": [
                                  "authorization_code",
                                  "implicit",
                                  "refresh_token"
                              ],
                              "issuer": "https://idp.example.com",
                              "jwks_uri": "https://idp.example.com/keys",
                              "token_endpoint": "https://idp.example.com/token",
                              "userinfo_endpoint": "https://idp.example.com/userinfo",
                              ...
                            }
                        

OpenID Connect Discovery 1.0

Hands-On Part

OAuth 2.0 & OpenID Connect 1.0

With Spring Security 5

“Legacy” Spring Security OAuth2 Stack

“New” Spring Security 5
OAuth2/OIDC Stack

“New” Spring Security 5
OAuth2/OIDC Stack

We will use THIS stack !!!

Let's Code!!

 

 

 

Make sure you have setup and started keycloak

THEN

Try the intro lab for Auth Code Demo

and follow instructions for Labs 5 & 6 in the
online tutorial

Starting Keycloak

...on Linux/Mac OS


                            [keycloak_install_dir]/bin/standalone.sh
                        
...on Windows

                            [keycloak_install_dir]\bin\standalone.bat
                        

Hands-On Labs

  • Intro-Lab: Authorization Code Flow Demo
  • Lab 5: OAuth2/OIDC Resource Server
  • Lab 6: OAuth2/OIDC Client (Auth Code Flow)

Please follow online tutorial in GitHub Repo

Intro-Lab

Authorization Code Grant Flow

In Action

See intro-labs/auth-code-demo for instructions

Labs 5 & 6: Resource Server and Client

Online Tutorial: Labs 5 & 6

Hands-On client & server

What's new in

Spring Security

5.2 & 5.3

Spring Security 5.2 (08/2019)

Spring Security 5.2.0 M2 GitHub Issues
Spring Security 5.2.0 M3 GitHub Issues
Spring Security 5.2.0 RC1 GitHub Issues

OAuth 2.0 Token Introspection

Opaque Tokens


                            class ResSrvConfig extends WebSecurityConfigurerAdapter {

                                @Override
                                protected void configure(HttpSecurity http)
                                        throws Exception {
                                    http.oauth2ResourceServer()
                                            .opaqueToken()
                                                .introspectionUri(this.introspectionUri)
                                                .introspectionClientCredentials(
                                                    this.clientId, this.clientSecret);
                                }
                            }
                        
https://github.com/spring-projects/spring-security/issues/5200

Resource Server Multi-tenancy


                            class ResSrvConfig extends WebSecurityConfigurerAdapter {

                                @Override protected void configure(HttpSecurity http) {
                                    http.oauth2ResourceServer()
                                        .authenticationManagerResolver(
                                            multitenantAuthenticationManager());
                                }

                                @Bean AuthenticationManagerResolver<HttpServletRequest>
                                    multiTenantAuthMgr() {...}

                                AuthenticationManager jwt() {...}
                                AuthenticationManager opaque() {...}
                            }
                        
https://github.com/spring-projects/spring-security/issues/5351
https://github.com/spring-projects/spring-security/issues/6727

Use symmetric keys with JwtDecoder


                            class ResSrvConfig extends WebSecurityConfigurerAdapter {

                              @Value("${spring.security.oauth2.resourceserver.
                                            jwt.key-value}") RSAPublicKey key;

                              @Override protected void configure(HttpSecurity http) {
                                http.oauth2ResourceServer().jwt().decoder(jwtDecoder());
                              }

                              @Bean JwtDecoder jwtDecoder() throws Exception {
                                  return NimbusJwtDecoder.
                                          withPublicKey(this.key).build();
                              }
                            }
                        
https://github.com/spring-projects/spring-security/issues/5465

JWT Flow API in Test Support


                            public class OAuth2ResourceServerTest {

                                @Test
                                public void testRequestPostProcessor() {
                                  mockMvc.perform(get("/message")
                                  .with(mockAccessToken().scope("message:read")))
                                  .andExpect(status().isOk())

                                  mockMvc.perform(get("/")
                                  .with(jwt().claim(SUB, "the-subject")))
                                  .andExpect(status().isOk())
                                }
                            }
                        
https://github.com/spring-projects/spring-security/issues/6634

Spring Security 5.3

Support OAuth 2.0 Authorization Server:

  • OAuth 2.0 Authorization Code Grant
  • OpenID Connect 1.0 (Authorization Code Flow)
  • PKCE
  • OAuth 2.0 Client Credentials Grant
  • JWT Access Token format
  • JWK Set Endpoint
  • Opaque Access Token format
  • OAuth 2.0 Token Revocation

Spring Security 5.3.0 GitHub Issues

Summary & References

Book References

Online References

All images used are from Pixabay and are published under Creative Commons CC0 license.

All used logos are trademarks of respective companies

Andreas Falk / @andifalk

Novatec Consulting GmbH
Dieselstraße 18/1
D-70771 Leinfelden-Echterdingen
andreas.falk@novatec-gmbh.de

https://www.novatec-gmbh.de