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