- Using Configuration for CORS
You can use configuration in combination with the Helidon CORS SE API to add CORS support to your resources by replacing some Java code with declarative configuration. This also gives your users a way to override the CORS behavior of your services without requiring the code to change.
Understanding the CORS Configuration Formats
Support in Helidon for CORS configuration uses two closely-related cross-origin configuration formats: basic and mapped. Each format corresponds to a class in the Helidon CORS library. The basic format corresponds to the CrossOriginConfig class, and the mapped format corresponds to the MappedCrossOriginConfig class.
Basic Cross-Origin Configuration
In configuration, Helidon represents basic CORS information as a section, identified by a configuration key of your choosing, that contains one or more key/value pairs. Each key-value pair assigns one characteristic of CORS behavior.
The table below lists the configuration keys that identify the CORS characteristics.
| Configuration Key | Default | CORS Header Name |
|---|---|---|
allow-credentials | false | Access-Control-Allow-Credentials |
allow-headers | ["*"] | Access-Control-Allow-Headers |
allow-methods | ["*"] | Access-Control-Allow-Methods |
allow-origins | ["*"] | Access-Control-Allow-Origins |
expose-headers | none | Access-Control-Expose-Headers |
max-age | 3600 | Access-Control-Max-Age |
enabled | true | n/a |
If the cross-origin configuration is disabled (enabled = false), then the Helidon CORS implementation ignores the cross-origin configuration entry.
The following example of basic cross-origin configuration, when loaded and used by the application, limits cross-origin resource sharing for PUT and DELETE operations to only foo.com and there.com:
...
restrictive-cors:
allow-origins: ["http://foo.com", "http://there.com"]
allow-methods: ["PUT", "DELETE"]
...Mapped Cross-Origin Configuration
In some cases, you or your users might want to configure CORS behavior based on URL path matching. Helidon represents mapped CORS information as a section, identified by a configuration key of your choosing, that contains:
An optional
enabledsetting which defaults totrueand applies to the whole mapped CORS config section, andAn optional
pathssubsection containing zero or more entries, each of which contains:a basic CORS config section, and
a
path-patternpath pattern that maps that basic CORS config section to the resource(s) it affects.
You can use mapped configuration to your advantage if you want to allow your users to override the CORS behavior set up in the application code.
The following example illustrates the mapped cross-origin configuration format.
...
my-cors:
paths:
- path-pattern: /greeting
allow-origins: ["http://foo.com", "http://there.com", "http://other.com"]
allow-methods: ["PUT", "DELETE"]
- path-pattern: /
allow-methods: ["GET", "HEAD", "OPTIONS", "POST"]
...- Assigns a unique identifier for this mapped CORS config section.
- Collects the sequence of entries, each of which maps a basic CORS config to a path pattern.
- Marks the beginning of an entry (the
-character) and maps the associated basic CORS config to the/greetingsubresource (thepath-patternkey and value). - Begins the basic CORS config section for
/greeting; it restricts sharing viaPUTandDELETEto the listed origins. - Marks the beginning of the next entry (the
-character) and maps the associated basic CORS config to the top-level resource in the app (thepath-patternkey and value). - Begins the basic CORS config section for
/; it permits sharing of resources at the top-level path with all origins for the indicated HTTP methods.
Path patterns can be any expression accepted by the PathMatcher class.
Be sure to arrange the entries in the order that you want Helidon to check them. Helidon CORS support searches the cross-origin entries in the order you define them until it finds an entry that matches an incoming request’s path pattern and HTTP method.
Using CORS Configuration in the Application
You use configuration in combination with the Helidon CORS SE API to add CORS support to your resources. The example in Sample Routing Setup Using the CrossOriginConfig API uses the low-level Helidon CORS SE API to create a CrossOriginConfig instance that is then used as part of a CorsSupport instance to create the routing rules. As an alternative to using the low-level API, this example uses config to create the CrossOriginConfig instance instead.
private static Routing createRouting(Config config) {
MetricsSupport metrics = MetricsSupport.create();
GreetService greetService = new GreetService(config);
HealthSupport health = HealthSupport.builder()
.addLiveness(HealthChecks.healthChecks()) // Adds a convenient set of checks
.build();
CorsSupport.Builder builder = CorsSupport.builder();
Config config = Config.create(); // Created from the current config sources
config.get("my-cors")
.ifExists(builder::mappedConfig);
config.get("restrictive-cors")
.ifExists(builder::config);
builder.addCrossOriginConfig(CrossOriginConfig.create());
CorsSupport corsSupport = builder.build();
// Note: Add the CORS routing *before* registering the GreetService routing.
return Routing.builder()
.register(JsonSupport.create())
.register(health) // Health at "/health"
.register(metrics) // Metrics at "/metrics"
.register("/greet", corsSupport, greetService)
.build();
}- If
my-corsexists in the configuration, use it to add mapped CORS config to theCorsSupportbuilder. - If
restrictive-corsexists in the configuration, use it to add basic (not mapped) config to the builder. - Provide default CORS handling for requests that do not match earlier entries.
- Obtain the finished
CorsSupportinstance. - Use
corsSupportin constructing the routing rules.
As each request arrives, Helidon checks it against the cross-origin config instances in the order that your application added them to the CorsSupport.Builder. The my-cors mapped configuration acts as an override because the application added it to the builder first.
If the my-cors config key does not appear in the configuration, then the code skips creating a CrossOriginConfig instance based on that configuration, and no overriding occurs. The CORS behavior that is established by the other CrossOriginConfig instance based on the restrictive-cors config (if present) prevails.
Remember that if you set configuration in a file that you include as part of your application JAR file, then you need to rebuild and restart your application for any changes to take effect.
Next Steps
Use these same configuration techniques to control the behavior of the CORS-enabled built-in services. Learn more.
See the Helidon CORS support in action by building and running the CORS example.