How to configure CORS in Quarkus applications

Configuring CORS in Quarkus 3.x requires enabling quarkus.http.cors=true in application.properties and defining your allowed origins, HTTP methods, and headers. Quarkus 3 processes CORS natively at the Vert.x HTTP layer, seamlessly integrating with Quarkus REST (RESTEasy Reactive) and Jakarta EE (jakarta.ws.rs.*) for optimal, non-blocking preflight request performance.

Here’s a step-by-step tutorial on how to configure Cross-Origin Resource Sharing (CORS) in Quarkus 3.x applications with just a few simple configuration tweaks.

Cross-Origin Resource Sharing (CORS) is a security mechanism enforced by web browsers to control how resources hosted on a server can be requested by another domain outside the origin server. This mechanism is essential for enabling secure cross-origin requests and data transfers between modern single-page applications (SPAs) and backend APIs.

You can find more details about CORS in this article: How to configure CORS on WildFly

Quarkus 3.x and Jakarta EE Context

Starting with Quarkus 3.x, the framework fully embraces Jakarta EE standards (migrating from javax.* to jakarta.* packages) and features Quarkus REST (formerly RESTEasy Reactive) as the default HTTP engine. Quarkus handles CORS preflight (OPTIONS) requests directly at the underlying Vert.x reactive engine level before reaching your Jakarta REST endpoints, ensuring maximum efficiency without blocking threads.

Step 1: Enable CORS in application.properties

First, enable the CORS filter in your Quarkus application. Add the following line to your src/main/resources/application.properties file:

quarkus.http.cors=true

Step 2: Configure Allowed Origins

Specify which origins are permitted to access your backend endpoints using the quarkus.http.cors.origins property. In Quarkus 3.x, you can pass comma-separated URLs or regular expressions enclosed in forward slashes:

# Plain origin URLs
quarkus.http.cors.origins=http://example.com,http://anotherdomain.com

# Alternatively, use regex patterns for dynamic domain matching (e.g., all subdomains)
# quarkus.http.cors.origins=/https?:\\/\\/.*\\.example\\.com/

Step 3: Configure Allowed Methods

Define the HTTP methods permitted during CORS requests via the quarkus.http.cors.methods property:

quarkus.http.cors.methods=GET,POST,PUT,DELETE,OPTIONS

Step 4: Configure Allowed Headers

Specify which HTTP headers can be sent in actual requests using the quarkus.http.cors.headers property:

quarkus.http.cors.headers=Content-Type,Authorization,X-Requested-With

Step 5: Configure Exposed Headers

If your frontend client needs access to custom backend response headers, expose them with quarkus.http.cors.exposed-headers:

quarkus.http.cors.exposed-headers=X-Custom-Header,X-Total-Count

Step 6: Configure Credentials

If your application relies on cookies, HTTP authentication, or client-side SSL certificates across origins, set quarkus.http.cors.access-control-allow-credentials to true:

quarkus.http.cors.access-control-allow-credentials=true

Step 7: Configure Preflight Cache Max Age

Specify how long the browser should cache the response of a preflight CORS request using quarkus.http.cors.access-control-max-age. In Quarkus 3.x, you can use standard duration syntax (e.g., 24h) or raw seconds:

quarkus.http.cors.access-control-max-age=24h

Complete Configuration Example

Here is a complete production-ready application.properties example for Quarkus 3.x:

quarkus.http.cors=true
quarkus.http.cors.origins=http://example.com,http://anotherdomain.com
quarkus.http.cors.methods=GET,POST,PUT,DELETE,OPTIONS
quarkus.http.cors.headers=Content-Type,Authorization
quarkus.http.cors.exposed-headers=X-Custom-Header
quarkus.http.cors.access-control-allow-credentials=true
quarkus.http.cors.access-control-max-age=24h

Jakarta EE / Mutiny Code Example

Here is an example of a Jakarta REST endpoint using Quarkus 3.x and Mutiny reactive streams. The CORS filter automatically intercepts requests before this endpoint receives them:

package com.mastertheboss.jaxrs;

import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import io.smallrye.mutiny.Uni;

@Path("/api/data")
public class CorsResource {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Uni<String> getData() {
        return Uni.createFrom().item("{\"status\": \"CORS configured successfully!\"}");
    }
}

Testing Your Configuration

To verify your CORS setup, you can perform a preflight test using curl from your terminal:

curl -v -X OPTIONS http://localhost:8080/api/data \
  -H "Origin: http://example.com" \
  -H "Access-Control-Request-Method: GET"

Check that the returned headers include Access-Control-Allow-Origin: http://example.com and the permitted methods.

Frequently Asked Questions (FAQs)

1. What happens if I set `quarkus.http.cors=true` without specifying origins?

If CORS is enabled without setting quarkus.http.cors.origins, Quarkus defaults to allowing all origins (*). However, if credential support (access-control-allow-credentials=true) is active, wildcard origins are not allowed by browser specifications, so explicit origins must be defined.

2. Do I need to create custom Jakarta REST filters for CORS in Quarkus 3.x?

No. Quarkus manages CORS efficiently at the Vert.x HTTP layer prior to entering the Jakarta REST pipeline. Using the built-in configuration properties is strongly recommended over writing custom JAX-RS/Jakarta REST filters.

3. Can I configure CORS dynamically per endpoint route?

The standard Quarkus CORS extension applies settings globally. If you need fine-grained dynamic CORS rules per route, you can implement a custom Vert.x @Observes Router or custom HTTP security policy within Quarkus.


Recommended Articles

A Comprehensive Comparison of WildFly Application Server and Quarkus Framework in Enterprise Java

Explore the features and use cases of WildFly and Quarkus for robust Java applications. #WildFly #Quarkus #EnterpriseJava

Create Standalone Quarkus Applications and Powerful Scripts Using JBang & Quarkus Command Mode

Learn how to develop standalone Quarkus applications with JBang and powerful scripts using Quarkus Command Mode. #Quarkus #Java #Microservices #CloudNative

Configure Default Transaction Timeout in Quarkus - A Comprehensive Guide

Learn how to configure and manage default transaction timeouts in Quarkus applications. #Quarkus #Java #Middleware

Optimizing Your Quarkus Application with Custom Undertow Server Settings

Learn how to customize your Quarkus application's embedded Undertow server settings. #Quarkus #Java #Middleware #CloudNative