/spring-boot-jwt-auth-server

Using JWTs issued by an external authorization server to authentication REST APIs with Spring Boot

Primary LanguageJavaScript

Spring Boot REST API JWT Authentication with an external Authorization Server

keywords: Spring Boot, REST API, JWT, Authentication, Authorization Server, OAuth2 Resource Server

Overview

NOTE: See the original article at JWT Authentication with OAuth2 Resource Server and an external Authorization Server

This is a demo to show how we can use the Spring Boot's OAuthResourceServer's jwt authentication to protect a REST API using OIDC/OAuth2 tokens (Access Tokens/JWT) obtained from an external authorization server.

  • frontend directory contains the example frontend

Getting Started

Backend

  1. Run the following command to build the backend
./mvnw clean install -DskipTests
  1. Start the JwtAuthIdentityProviderApplication main class to start the REST API. It will start at http://localhost:8080

Frontend (React.js Example)

  1. Run the following command to build and start the frontend (within the frontend directory):
npm install
npm start

The frontend React.js app will start at http://localhost:3000

Solution Overview

Authorization Code Flow

sequenceDiagram
    actor User
    participant SPA as Single Page Application<br/>(Browser)
    participant Auth as Authorization Server
    
    activate User
    activate SPA
    User -->> SPA: open web application
    SPA ->> SPA: show login page
    
    User -->> SPA: click "login"
    
    activate Auth
    SPA ->> Auth: redirect to auth server<br/>https://auth-server.com/authorize
    Note over SPA,Auth: this redirect contains the "grant_type" and<br/>requested "scopes"
    Auth ->> Auth: show login page
    User -->> Auth: login
    Auth ->> SPA: redirect to SPA<br/>https://webapp.com/auth-callback?code=xxxx
    Note over SPA, Auth: the redirect URI has the authorization code<br/>as a query parameter
    
    SPA ->> Auth: get access token<br/>https://auth-server.com/token
    Note right of SPA: /token request includes the "auth code" received
    Auth ->> SPA: id_token and access_token
    
    deactivate Auth
    SPA ->> SPA: validate id_token
    SPA ->> SPA: login user to the app
    SPA -->> User: show functionalities
    
    deactivate SPA
    deactivate User
Loading

Invoking the backend REST API

sequenceDiagram
    autonumber
    
    actor User
    participant SPA as Single Page Application<br/>(Browser)
    participant Filter as OAuth2 Resource Server<br>(Backend)
    participant API as Product REST API<br>(Backend)
    participant Auth as Authorization Server<br>(External)
    
    activate User
    activate SPA
    
    User -->> SPA: list products
    
    activate Filter
    
    SPA ->> Filter: GET https://api.com/products
    Note right of SPA: Include authorization header<br/>Authorization: Bearer ${access_token}
    
    Filter ->> Filter: validate JWT in "Authorization" header
    
    activate Auth
    rect rgb(191, 223, 255)
    Filter ->> Auth: get JWKS from authorization server<br/>https://auth-server.com/jwks
    Note over Filter,Auth: Obtaining JWKS is a one time task<br/>and will be cached for future usage
    Auth ->> Filter: JWKS (Json Web Key Set)
    end
    deactivate Auth
    
    alt JWT valid
        activate API
        Filter ->> API: Forward to /products service
        API ->> API: Fetch products from DB
        API ->> SPA: products list
        deactivate API
        SPA -->> User: show product list
    else JWT not valid
        Filter ->> SPA: Unauthorized
        SPA -->> User: show not permitted error
    end
    
    deactivate Filter
    
    deactivate User
    deactivate SPA

Loading