VOOZH about

URL: https://dzone.com/articles/jwt-policy-enforcement-raml-anypoint-platform

⇱ JWT Policy Enforcement, API Security with RAML in Anypoint


Related

  1. DZone
  2. Software Design and Architecture
  3. Security
  4. JWT Policy Enforcement, Rate Limiting, IP White Listing: Using Mulesoft, API Security, Cloudhub 2.0

JWT Policy Enforcement, Rate Limiting, IP White Listing: Using Mulesoft, API Security, Cloudhub 2.0

Learn how to enforce JWT policies in API Manager with a RAML project. Secure endpoints using Auth0, plus apply IP whitelisting and rate limiting in Anypoint.

By Aug. 07, 25 · Tutorial
Likes
Comment
Save
2.2K Views

Join the DZone community and get the full member experience.

Join For Free

This tutorial is all about implementing JWT Policy Enforcement in API Manager using a sample RAML-based project. It's especially helpful when applying policies through the API Manager in the Anypoint Platform. Along the way, you’ll also learn how to secure a specific API endpoint using a third-party Auth Provider like Auth0.

In this project, the following policies have been applied to enhance API security and traffic control:

  • JWT Policy Enforcement
  • IP Whitelisting
  • Rate Limiting

Prerequisites

  • Anypoint Studeio 7.21 (Java 17 Compatible default)
  • Java 17
  • Anypoint Platform account
  • SOAPUI + POSTMAN
  • Maven

Watch the video tutorial for a complete walkthrough of the concept.

Refer to the diagram to understand how the JWT (JSON Web Token) authentication process works.

JWT Authentication Process


  1. The client first calls the Auth Provider to obtain a token by sending the client ID, client secret, and grant_type.
  2. Once the token is received, the client uses it to call the actual resource server endpoint.
  3. The resource server then validates the token by making a call to the Auth Provider.
  4. If the token is valid, a 200 OK response is returned to the client.
  5. If the token is invalid, an error response is sent back.

I’ve included the relevant RAML file details below for reference.


The following RAML files define the API security schemes used in this project:

jwt-token.raml

This file defines the JWT-based security scheme, specifying how tokens should be passed and validated.

XML
#%RAML 1.0 SecurityScheme
type: x-jwt
description: |
 This API uses JWT for authentication. Pass the token in the Authorization header as "Bearer {token}".
describedBy:
 headers:
 Authorization:
 description: |
 JWT access token in the format "Bearer {token}".
 type: string
 required: true
 example: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
 responses:
 401:
 description: |
            Unauthorized. JWT is missing, invalid, or expired.


oauth2.raml

This file defines the OAuth 2.0 security scheme, where clients must obtain an access token and include it in the Authorization header as "Bearer {token}". It supports common grant types like authorization_code and client_credentials, along with scoped access control.

XML
#%RAML 1.0 SecurityScheme
type: OAuth 2.0
description: |
 This API is secured using OAuth 2.0. Obtain an access token and include it in the Authorization header as "Bearer {token".
describedBy:
 headers:
 Authorization:
 description: |
 Used to send the OAuth 2.0 access token. Format: "Bearer {token}".
 type: string
 required: true
 example: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
 responses:
 401:
 description: |
 Unauthorized. Access token is missing, invalid, or expired.
 403:
 description: |
 Forbidden. The access token does not have the required scopes or permissions.
settings:
 authorizationUri: https://auth.example.com/oauth2/authorize
 accessTokenUri: https://auth.example.com/oauth2/token
 authorizationGrants: [ authorization_code, client_credentials ]
      scopes: [ read, write, admin ]


basic-auth-details.xml

This file defines the Basic Authentication scheme using a standard username and password passed in the Authorization header.

XML
#%RAML 1.0 SecurityScheme
type: Basic Authentication
description: |
 Basic Authentication using username and password.
describedBy:
 headers:
 Authorization:
 description: |
 Standard HTTP Basic Authentication header. Value must be "Basic base64(username:password)".
 type: string
 required: true
 responses:
 401:
 description: Unauthorized. Invalid or missing credentials.


The trait file is defined as follows:

XML
#%RAML 1.0 Trait
usage: Apply to collection GET endpoints to support pagination.
queryParameters:
 page:
 type: integer
 required: false
 minimum: 1
 default: 1
 description: The page number to retrieve (starting from 1).
 example: 2
 pageSize:
 type: integer
 required: false
 minimum: 1
 maximum: 100
 default: 20
 description: The number of items per page.
 example: 10
responses:
 200:
 headers:
 X-Total-Count:
 type: integer
 description: Total number of items available.
 example: 57
 X-Total-Pages:
 type: integer
 description: Total number of pages available.
 example: 6
 X-Current-Page:
 type: integer
 description: The current page number.
 example: 2
 X-Page-Size:
 type: integer
 description: The number of items per page in this response.
        example: 10


TYPE RAML Files

The following RAML files define the data types used across the API:

Booking.raml

Defines the Booking data type, including fields like id, hotelId, guestName, checkInDate, checkOutDate, rooms, and status. It represents a complete hotel booking with validation and example data.

XML
#%RAML 1.0 DataType
type: object
properties:
 id:
 type: integer
 description: Unique booking identifier
 example: 1001
 hotelId:
 type: integer
 description: ID of the booked hotel
 example: 101
 guestName:
 type: string
 required: true
 description: Name of the guest
 example: "Alice Smith"
 checkInDate:
 type: date-only
 required: true
 description: Check-in date
 example: 2024-07-01
 checkOutDate:
 type: date-only
 required: true
 description: Check-out date
 example: 2024-07-05
 rooms:
 type: integer
 required: true
 minimum: 1
 description: Number of rooms booked
 example: 2
 status:
 type: string
 enum: [ confirmed, cancelled, pending ]
 description: Booking status
 example: confirmed
example:
 id: 1001
 hotelId: 101
 guestName: "Alice Smith"
 checkInDate: 2024-07-01
 checkOutDate: 2024-07-05
 rooms: 2
 status: confirmed


BookingInput.raml

Outlines the required data format for submitting a hotel booking request. It includes required fields such as hotelId, guestName, checkInDate, checkOutDate, and rooms, with validation rules for each. This file excludes fields like id and status, which are typically set by the system.

XML
#%RAML 1.0 DataType
 type: object
 properties:
 hotelId:
 type: integer
 required: true
 guestName:
 type: string
 required: true
 checkInDate:
 type: date-only
 required: true
 checkOutDate:
 type: date-only
 required: true
 rooms:
 type: integer
 required: true
 minimum: 1
 example:
 hotelId: 101
 guestName: "Alice Smith"
 checkInDate: 2024-07-01
 checkOutDate: 2024-07-05
      rooms: 2


ErrorResponse.raml

Defines a standard error response object containing a single required property: message. This message provides details about the error encountered, such as missing resources, invalid inputs, or authentication failures.

XML
#%RAML 1.0 DataType
 type: object
 properties:
 message:
 type: string
 required: true
 description: Error message
 example:
      message: "Resource not found."


Hotel.raml

Represents the full Hotel data type used in API responses. It includes properties like:

  • id: Unique identifier for the hotel
  • name: Hotel name (required)
  • address: Hotel address (required)
  • rating: Optional float value (1–5) indicating the hotel’s rating
  • amenities: Optional list of available features (e.g., "wifi", "pool")

XML
#%RAML 1.0 DataType
type: object
description: Data type for hotel
properties:
 id:
 type: integer
 description: Unique hotel identifier
 example: 101
 name:
 type: string
 required: true
 description: Name of the hotel
 example: "Grand Plaza"
 address:
 type: string
 required: true
 description: Address of the hotel
 example: "123 Main St, Cityville"
 rating?:
 type: number
 format: float
 minimum: 1
 maximum: 5
 description: Hotel rating (1-5 stars)
 example: 4.5
 amenities?:
 type: array
 items: string
 description: List of amenities
 example: [ "wifi", "pool", "gym" ]
example:
 id: 101
 name: "Grand Plaza"
 address: "123 Main St, Cityville"
 rating: 4.5
 amenities: [ "wifi", "pool", "gym" ]
additionalProperties: false


HotelInput.raml

Specifies the format and required details for submitting a new hotel booking. It includes:

  • name (string, required): The hotel’s name
  • address (string, required): The hotel’s address
  • rating (number, optional): Hotel rating from 1 to 5 (float)
  • amenities (array of strings, optional): List of hotel amenities like "wifi", "pool", "gym"

This type is used when sending hotel details in POST or PUT requests.

XML
#%RAML 1.0 DataType
type: object
properties:
 name:
 type: string
 required: true
 address:
 type: string
 required: true
 rating?:
 type: number
 format: float
 minimum: 1
 maximum: 5
 amenities?:
 type: array
 items: string
example:
 name: "Grand Plaza"
 address: "123 Main St, Cityville"
 rating: 4.5
 amenities: [ "wifi", "pool", "gym" ]
additionalProperties: false


order-api-security.raml

This RAML file defines the hotel booking API with security and data types included:

  • Title: order-api-security
  • Description: API for hotel booking management
  • Media Type: application/json
  • Protocols: HTTP
  • Version: v1
  • Base URI:http://api.example.com/hotel-booking/v1

Security Schemes:

  • Basic Authentication
  • OAuth 2.0
  • JWT Token

Traits:

  • Pagination support applied to GET collections

Data Types Included:

  • Hotel
  • HotelInput
  • Booking
  • BookingInput
  • ErrorResponse

Endpoints:

  • /hotels for listing and creating hotels (with pagination for GET)
  • /hotels/{hotelId} for retrieving, updating, and deleting specific hotels

The API is secured by basicAuth, oAuth2, and jwtToken schemes.

XML
#%RAML 1.0
title: order-api-security
description: "This api contain the hotel booking details"
mediaType: 
- application/json
protocols:
 - HTTP
version: v1
baseUri: http://api.example.com/hotel-booking/v1
securitySchemes:
 basicAuth: !include AUTH/basic-auth-details.raml
 oAuth2: !include AUTH/oauth2.raml
 jwtToken: !include AUTH/jwt-token.raml
traits:
 paginated: !include TRAIT/trait.raml

types:
 Hotel: !include TYPE/Hotel.raml
 HotelInput: !include TYPE/HotelInput.raml
 Booking: !include TYPE/Booking.raml
 BookingInput: !include TYPE/BookingInput.raml
 ErrorResponse: !include TYPE/ErrorResponse.raml

securedBy: [ basicAuth, oAuth2,jwtToken]

/hotels:
 get:
 description: Get a paginated list of hotels.
 is: [ paginated ]
 responses:
 200:
 description: Successful response with a list of hotels.
 body:
 application/json:
 type: Hotel[]
 example:
 - id: 101
 name: "Grand Plaza"
 address: "123 Main St, Cityville"
 rating: 4.5
 amenities: [ "wifi", "pool", "gym" ]
 - id: 102
 name: "Ocean View"
 address: "456 Beach Rd, Seaside"
 rating: 4.0
 amenities: [ "wifi", "spa" ]
 post:
 description: Create a new hotel.
 body:
 application/json:
 type: HotelInput
 example:
 name: "Grand Plaza"
 address: "123 Main St, Cityville"
 rating: 4.5
 amenities: [ "wifi", "pool", "gym" ]
 responses:
 201:
 description: Hotel created successfully.
 body:
 application/json:
 type: Hotel
 example:
 id: 103
 name: "Mountain Retreat"
 address: "789 Hilltop Ave, Mountainview"
 rating: 5
 amenities: [ "wifi", "sauna" ]

/hotels/{hotelId}:
 uriParameters:
 hotelId:
 type: integer
 required: true
 description: Unique hotel identifier
 example: 101
 get:
 description: Get details of a specific hotel.
 responses:
 200:
 description: Successful response with hotel details.
 body:
 application/json:
 type: Hotel
 example:
 id: 101
 name: "Grand Plaza"
 address: "123 Main St, Cityville"
 rating: 4.5
 amenities: [ "wifi", "pool", "gym" ]
 put:
 description: Update details of a specific hotel
 body:
 application/json:
 type: HotelInput
 example:
 name: "Grand Plaza Updated"
 address: "123 Main St, Cityville"
 rating: 4.7
 amenities: [ "wifi", "pool", "gym", "spa" ]
 responses:
 200:
 description: Hotel updated successfully.
 body:
 application/json:
 type: Hotel
 example:
 id: 101
 name: "Grand Plaza Updated"
 address: "123 Main St, Cityville"
 rating: 4.7
 amenities: [ "wifi", "pool", "gym", "spa" ]
 delete:
 description: Delete a specific hotel.
 responses:
 204:
        description: Hotel deleted successfully. No content.


Now, publish your API to Exchange.

To implement the project locally, choose the scaffolding option shown below.


For implementation and auto-discovery, I assume you’re already familiar, so I won’t cover the details here.

Once everything looks good, deploy the project to CloudHub 2.0, where it should appear as running.


Now, log in or sign up with the Auth0 provider to obtain the JWKS URL.

Navigate to Auth0 > My Profile > Applications > Settings > Endpoints.

Copy the JWKS URL and paste it into the JWT policy configuration within the API Manager as demonstrated below.





The next step is to obtain the token. You’ll need the following four pieces of information to request it. (Note: The client secret shown here is modified for security.)

JSON
{
 "client_id":"j5WYzDUApVpIT9QbXQ6IHHXDcAHYrvP1",
 "client_secret":"hnQmxxsxsxsxsxsoL73qxqOmX1fDV37SN4wYjEMhhkj05d-xlR4oeKExY8PFDYm39iL",
 "audience":"https://dev-0qcnlhjb6rx4ckcw.us.auth0.com/api/v2/",
 "grant_type":"client_credentials"
  }



Next, use the token to call the actual API. If the token is valid, you’ll receive the expected response.


If the token is invalid, you will receive a 401 Unauthorized response.


The IP Allow List policy and Rate Limiting are straightforward—please refer to the video for detailed explanation.

If you found this tutorial helpful, please give it a like and feel free to ask any questions you may have!

API JWT (JSON Web Token) security

Opinions expressed by DZone contributors are their own.

Related

  • Implementing Secure API Gateways for Microservices Architecture
  • Protecting PII Data With JWT
  • Secure Your API With JWT: Kong OpenID Connect
  • Securing REST APIs With Nest.js: A Step-by-Step Guide

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

Let's be friends: