Package io.helidon.webserver.cors

Helidon SE CORS Support

Use CorsSupport and its CorsSupport.Builder to add CORS handling to resources in your application.

Because Helidon SE does not use annotation processing to identify endpoints, you need to provide the CORS information for your application another way. You can use Helidon configuration, the Helidon CORS API, or a combination.

Configuration

Format

CORS configuration looks like this:
 enabled: true    # the default
 allow-origins: ["http://foo.bar", "http://bar.foo"]
 allow-methods: ["DELETE", "PUT"]
 allow-headers: ["X-bar", "X-foo"]
 allow-credentials: true
 max-age: -1
 

Finding and applying CORS configuration

Although Helidon prescribes the CORS config format, you can put it wherever you want in your application's configuration file. Your application code will retrieve the CORS config from its location within your configuration and then use that config node to prepare CORS support for your app. For example, if you set up this configuration
 narrow:
   allow-origins: ["http://foo.bar", "http://bar.foo"]
   allow-methods: ["DELETE", "PUT"]
   allow-headers: ["X-bar", "X-foo"]
   allow-credentials: true
   max-age: -1

 wide:
   enabled: false
   allow-origins: ["*"]
   allow-methods: ["*"]

 just-disabled:
   enabled: false
 

in a resource called myApp.yaml then the following code would apply it to your app:


         Config myAppConfig = Config.builder().sources(ConfigSources.classpath("myApp.yaml")).build();
         Routing.Builder builder = Routing.builder();
         myAppConfig.get("narrow").ifPresent(c -> builder.any(
                          "/greet", CorsSupport.create(c),
                          (req, resp) -> resp.status(Http.Status.OK_200).send()));
         myAppConfig.get("wide".ifPresent(c -> builder.get(
                          "/greet", CorsSupport.create(c),
                          (req, resp) -> resp.status(Http.Status.OK_200).send("Hello, World!")));
     
This sets up more restrictive CORS behavior for more sensitive HTTP methods (PUT for example) and more liberal CORS behavior for GET.

The Helidon CORS API

You can define your application's CORS behavior programmatically -- together with configuration if you want -- by:
  • creating a CrossOriginConfig.Builder instance,
  • operating on the builder to prepare the CORS set-up you want,
  • using the builder's build() method to create the CrossOriginConfig instance, and

The next example shows creating CORS information and associating it with the path /cors3 within the app.

         CrossOriginConfig corsForCORS3= CrossOriginConfig.builder()
             .allowOrigins("http://foo.bar", "http://bar.foo")
             .allowMethods("DELETE", "PUT")
             .build();

         Routing.Builder builder = Routing.builder()
                 .register("/myapp",
                           CorsSupport.builder()
                                 .addCrossOrigin("/cors3", corsForCORS3) // links the CORS info with a path within the app
                                 .build(),
                           new MyApp());
 
Notice that you pass two services to the register method: the CorsSupport instance and your app instance. Helidon will process requests to the path you specify with those services in that order. Also, note that you have to make sure you use the same path in this API call and in your MyApp service if you adjust the routing there.

Invoke addCrossOrigin multiple times to link more paths with CORS configuration. You can reuse one CrossOriginConfig object with more than one path if that meets your needs.

Remember that the CORS protocol uses the OPTIONS HTTP method for preflight requests. If you use the handler-based methods on Routing.Builder be sure to invoke the options method as well (or {code any}) to set up routing for OPTIONS requests.

Each CorsSupport instance can be enabled or disabled, either through configuration or using the API. By default, when an application creates a new CorsSupport.Builder instance that builder's build() method will create an enabled CorsSupport object. Any subsequent explicit setting on the builder, either expressly set by an enabled entry in configuration passed to CorsSupport.Builder.config or set by invoking CorsSupport.Builder.enabled follows the familiar "latest-wins" approach.