LIGHT

  • News
  • Docs
  • Community
  • Reddit
  • GitHub

OpenAPI Security

This module is part of light-rest-4j, built on top of light-4j but focused on RESTful API security only. It only works with the OpenAPI 3.0 specification.

The JwtVerifyHandler supports OAuth2 with JWT token distributed verification and can be extended to other authentication and authorization approaches with UnifiedSecurityHandler.

JwtVerifyHandler

This is the handler that is injected during server startup if security.yml enableVerifyJwt is true. It does further scope verification if enableVerifyScope is true against OpenAPI specification.

From release 1.5.18, Light4J supports multiple chains of middleware handlers and multiple frameworks mixed in the same service instance. In order to have a security configuration file for each framework, a new openapi-security.yml with the same content has been introduced. The security.yml is still loaded if openapi-security.yml doesn’t exist for backward compatibility.

Here is a built-in openapi-security.yml in the module with default configurations.

# Security configuration for openapi-security in light-rest-4j. It is a specific config
# for OpenAPI framework security. It is introduced to support multiple frameworks in the
# same server instance. If this file cannot be found, the generic security.yml will be
# loaded for backward compatibility.
---
# Enable the JWT verification flag. The JwtVerifierHandler will skip the JWT token verification
# if this flag is false. It should only be set to false on the dev environment for testing
# purposes. If you have some endpoints that want to skip the JWT verification, you can put the
# request path prefix in skipPathPrefixes.
enableVerifyJwt: ${openapi-security.enableVerifyJwt:true}

# Enable the SWT verification flag. The SwtVerifierHandler will skip the SWT token verification
# if this flag is false. It should only be set to false on the dev environment for testing
# purposes. If you have some endpoints that want to skip the SWT verification, you can put the
# request path prefix in skipPathPrefixes.
enableVerifySwt: ${openapi-security.enableVerifySwt:true}

# Extract JWT scope token from the X-Scope-Token header and validate the JWT token
enableExtractScopeToken: ${openapi-security.enableExtractScopeToken:true}

# Enable JWT scope verification. This flag is valid when enableVerifyJwt is true. When using the
# light gateway as a centralized gateway without backend API specifications, you can still enable
# this flag to allow the admin endpoints to have scopes verified. And all backend APIs without
# specifications skip the scope verification if the spec does not exist with the skipVerifyScopeWithoutSpec
# flag to true. Also, you need to have the openapi.yml specification file in the config folder to
# enable it, as the scope verification compares the scope from the JWT token and the scope in the
# endpoint specification.
enableVerifyScope: ${openapi-security.enableVerifyScope:true}

# Users should only use this flag in a shared light gateway if the backend API specifications are
# unavailable in the gateway config folder. If this flag is true and the enableVerifyScope is true,
# the security handler will invoke the scope verification for all endpoints. However, if the endpoint
# doesn't have a specification to retrieve the defined scopes, the handler will skip the scope verification.
skipVerifyScopeWithoutSpec: ${openapi-security.skipVerifyScopeWithoutSpec:false}

# If set true, the JWT verifier handler will pass if the JWT token is expired already. Unless
# you have a strong reason, please use it only on the dev environment if your OAuth 2 provider
# doesn't support long-lived token for dev environment or test automation.
ignoreJwtExpiry: ${openapi-security.ignoreJwtExpiry:false}

# set true if you want to allow http 1/1 connections to be upgraded to http/2 using the UPGRADE method (h2c).
# By default this is set to false for security reasons. If you choose to enable it make sure you can handle http/2 w/o tls.
enableH2c: ${openapi-security.enableH2c:false}

# User for test only. should be always be false on official environment.
enableMockJwt: ${openapi-security.enableMockJwt:false}

# JWT signature public certificates. kid and certificate path mappings.
jwt:
  certificate: ${openapi-security.certificate:100=primary.crt&101=secondary.crt}
#    '100': primary.crt
#    '101': secondary.crt
  clockSkewInSeconds: ${openapi-security.clockSkewInSeconds:60}
  # Key distribution server standard: JsonWebKeySet for other OAuth 2.0 provider| X509Certificate for light-oauth2
  keyResolver: ${openapi-security.keyResolver:JsonWebKeySet}

# Enable or disable JWT token logging for audit. This is to log the entire token
# or choose the next option that only logs client_id, user_id and scope.
logJwtToken: ${openapi-security.logJwtToken:true}

# Enable or disable client_id, user_id and scope logging if you don't want to log
# the entire token. Choose this option or the option above.
logClientUserScope: ${openapi-security.logClientUserScope:false}

# Enable JWT token cache to speed up verification. This will only verify expired time
# and skip the signature verification as it takes more CPU power and a long time. If
# each request has a different jwt token, like authorization code flow, this indicator
# should be turned off. Otherwise, the cached jwt will only be removed after 15 minutes
# and the cache can grow bigger if the number of requests is very high. This will cause
# memory kill in a Kubernetes pod if the memory setting is limited.
enableJwtCache: ${openapi-security.enableJwtCache:true}

# If enableJwtCache is true, then an error message will be shown up in the log if the
# cache size is bigger than the jwtCacheFullSize. This helps the developers to detect
# cache problem if many distinct tokens flood the cache in a short period of time. If
# you see JWT cache exceeds the size limit in logs, you need to turn off the enableJwtCache
# or increase the cache full size to a bigger number from the default 100.
jwtCacheFullSize: ${openapi-security.jwtCacheFullSize:100}

# If you are using light-oauth2, then you don't need to have oauth subfolder for public
# key certificate to verify JWT token, the key will be retrieved from key endpoint once
# the first token is arrived. Default to false for dev environment without oauth2 server
# or official environment that use other OAuth 2.0 providers.
bootstrapFromKeyService: ${openapi-security.bootstrapFromKeyService:false}

# Used in light-oauth2 and oauth-kafka key service for federated deployment. Each instance
# will have a providerId, and it will be part of the kid to allow each instance to get the
# JWK from other instance based on the providerId in the kid.
providerId: ${openapi-security.providerId:}

# Define a list of path prefixes to skip the security to ease the configuration for the
# handler.yml so that users can define some endpoint without security even through it uses
# the default chain. This is particularly useful in the light-gateway use case as the same
# instance might be shared with multiple consumers and providers with different security
# requirement. The format is a list of strings separated with commas or a JSON list in
# values.yml definition from config server, or you can use yaml format in this file.
skipPathPrefixes: ${openapi-security.skipPathPrefixes:}

# When light-gateway or http-sidecar is used for security, sometimes, we need to pass some
# claims from the JWT or SWT to the backend API for further verification or audit. You can
# select some claims to pass to the backend API with HTTP headers. The format is a map of
# claim in the token and a header name that the downstream API is expecting. You can use
# both JSON or YAML format.
# When SwtVerifyHandler is used, the claim names are in https://github.com/networknt/light-4j/blob/master/client/src/main/java/com/networknt/client/oauth/TokenInfo.java
# When JwtVerifyHandler is used, the claim names is the JwtClaims claimName.
# YAML
# openapi-security.passThroughClaims:
#   clientId: client_id
#   tokenType: token_type
# JSON
# openapi-security.passThroughClaims: {"clientId":"client_id","tokenType":"token_type"}
passThroughClaims: ${openapi-security.passThroughClaims:}

For detailed information about the properties in the above configuration file, please refer to the light-4j security module.

Unlike the simple web token that the resource server has to contact the Authorization server to validate, JWT can be verified by the resource server as long as the token signing certificate is available at the resource server or there is a JWK link available to the resource server.

For some legacy applications that use http-sidecar or light-gateway as light-proxy-server(LPS) on the same host with native service, they might require that the JwtVerifyHandler passes through some token claims to the backend API through HTTP headers for further verification or audit. To do that, you need to add the openapi-security.passThroughClaims to the values.yml like the following.

openapi-security.passThroughClaims: {"clientId":"client_id", "tokenType":"token_type"}

Or

openapi-security.passThroughClaims: 
  clientId: client_id
  tokenType: token_type

The passThroughClaims is a map with the key as the claim name in the JWT token, and the value is the header name to pass to the backend API. You can check the claim names with jwt.io website by pasting the JWT token there.

SwtVerifyHandler

Some OAuth 2.0 providers issue a simple web token as an access token if the client requests come from the Internet for security reasons. The resource server has to use that token to invoke the token introspection endpoint to get all the details about the token, including the scope.

This handler shares the same openapi-security.yml configuration file with the JwtVerifyHandler. By default, the JwtVerifyHandler is enabled, and this handler is disabled. To use SwtVerifyHandler, we need to inject the SwtVerifyHandler in the handler chain like the following.

handler.yml

handler.handlers:
  .
  .
  .
  - com.networknt.openapi.SwtVerifyHandler@security
  .
  .
  .

handler.chains.default:
  .
  .
  .
  - security
  .
  .
  .

In the values.yml file, we need to disable the jwt handler and enable this handler.

values.yml

openapi-security.enableVerifyJwt: false
openapi-security.enableVerifySwt: true

We also need to set up the token introspection URL and credentials in the client.yml section in values.yml

client.tokenKeyServerUrl: https://oauth.networknt.com
client.tokenKeyUri: /oauth/introspection
client.tokenKeyClientId: f7d42348-c647-4efb-a52d-4c5787421e72
client.tokenKeyClientSecret: f6h1FTI8Q3-7UScPZDzfXA
client.tokenKeyEnableHttp2: true

As you can see, the configuration is the same for loading the JWKs from the OAuth provider for JWT verification. The above is for a single OAuth 2.0 provider. For multiple OAuth 2.0 providers with different introspection endpoints, please see the UnifiedSecurityHandler for details.

For some legacy applications that use http-sidecar or light-gateway as light-proxy-server(LPS) on the same host with native service, they might require that the SwtVerifyHandler passes through some token claims to the backend API through HTTP headers for further verification or audit. To do that, you need to add the openapi-security.passThroughClaims to the values.yml like the following.

openapi-security.passThroughClaims: {"clientId":"client_id", "tokenType":"token_type"}

Or

openapi-security.passThroughClaims: 
  clientId: client_id
  tokenType: token_type

The passThroughClaims is a map with the key as the property name in TokenInfo, and the value is the header name to passed to the backend API.

UnifiedSecurityHandler

This all-in-one security handler combines Basic, OAuth and API Key to be used in a shared light-gateway instance to handle multiple consumers and providers. For configuration and usage, please visit UnifiedSecurityHandler in the light-gateway.

  • About Light
    • Overview
    • Testimonials
    • What is Light
    • Features
    • Principles
    • Benefits
    • Roadmap
    • Community
    • Articles
    • Videos
    • License
    • Why Light Platform
  • Getting Started
    • Get Started Overview
    • Environment
    • Light Codegen Tool
    • Light Rest 4j
    • Light Tram 4j
    • Light Graphql 4j
    • Light Hybrid 4j
    • Light Eventuate 4j
    • Light Oauth2
    • Light Portal Service
    • Light Proxy Server
    • Light Router Server
    • Light Config Server
    • Light Saga 4j
    • Light Session 4j
    • Webserver
    • Websocket
    • Spring Boot Servlet
  • Architecture
    • Architecture Overview
    • API Category
    • API Gateway
    • Architecture Patterns
    • CQRS
    • Eco System
    • Event Sourcing
    • Fail Fast vs Fail Slow
    • Integration Patterns
    • JavaEE declining
    • Key Distribution
    • Microservices Architecture
    • Microservices Monitoring
    • Microservices Security
    • Microservices Traceability
    • Modular Monolith
    • Platform Ecosystem
    • Plugin Architecture
    • Scalability and Performance
    • Serverless
    • Service Collaboration
    • Service Mesh
    • SOA
    • Spring is bloated
    • Stages of API Adoption
    • Transaction Management
    • Microservices Cross-cutting Concerns Options
    • Service Mesh Plus
    • Service Discovery
  • Design
    • Design Overview
    • Design First vs Code First
    • Desgin Pattern
    • Service Evolution
    • Consumer Contract and Consumer Driven Contract
    • Handling Partial Failure
    • Idempotency
    • Server Life Cycle
    • Environment Segregation
    • Database
    • Decomposition Patterns
    • Http2
    • Test Driven
    • Multi-Tenancy
    • Why check token expiration
    • WebServices to Microservices
  • Cross-Cutting Concerns
    • Concerns Overview
  • API Styles
    • Light-4j for absolute performance
    • Style Overview
    • Distributed session on IMDG
    • Hybrid Serverless Modularized Monolithic
    • Kafka - Event Sourcing and CQRS
    • REST - Representational state transfer
    • Web Server with Light
    • Websocket with Light
    • Spring Boot Integration
    • Single Page Application
    • GraphQL - A query language for your API
    • Light IBM MQ
    • Light AWS Lambda
    • Chaos Monkey
  • Infrastructure Services
    • Service Overview
    • Light Proxy
    • Light Mesh
    • Light Router
    • Light Portal
    • Messaging Infrastructure
    • Centralized Logging
    • COVID-19
    • Light OAuth2
    • Metrics and Alerts
    • Config Server
    • Tokenization
    • Light Controller
  • Tool Chain
    • Tool Chain Overview
  • Utility Library
  • Service Consumer
    • Service Consumer
  • Development
    • Development Overview
  • Deployment
    • Deployment Overview
    • Frontend Backend
    • Linux Service
    • Windows Service
    • Install Eventuate on Windows
    • Secure API
    • Client vs light-router
    • Memory Limit
    • Deploy to Kubernetes
  • Benchmark
    • Benchmark Overview
  • Tutorial
    • Tutorial Overview
  • Troubleshooting
    • Troubleshoot
  • FAQ
    • FAQ Overview
  • Milestones
  • Contribute
    • Contribute to Light
    • Development
    • Documentation
    • Example
    • Tutorial
“OpenAPI Security” was last updated: February 22, 2023: fixes #365 update the openapi-security doc to add passThroughClaims (592e764)
Improve this page
  • News
  • Docs
  • Community
  • Reddit
  • GitHub
  • About Light
  • Getting Started
  • Architecture
  • Design
  • Cross-Cutting Concerns
  • API Styles
  • Infrastructure Services
  • Tool Chain
  • Utility Library
  • Service Consumer
  • Development
  • Deployment
  • Benchmark
  • Tutorial
  • Troubleshooting
  • FAQ
  • Milestones
  • Contribute