All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mp.cors.cors.adoc Maven / Gradle / Ivy

There is a newer version: 4.1.1
Show newest version
///////////////////////////////////////////////////////////////////////////////

    Copyright (c) 2022, 2024 Oracle and/or its affiliates.

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

        http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.

///////////////////////////////////////////////////////////////////////////////

= CORS in Helidon MP
:toc:
:toc-placement: preamble
:description: Helidon MP CORS Support
:keywords: helidon, java, cors, mp, configuration, services
:feature-name: CORS
:cors-config-key-explanation: , identified by a configuration key of your choosing,
:mapped-config-top-key: cors
:mapped-config-id-callout: The unique identifier for this mapped CORS config section must be `cors`.
:basic-table-intro: The table below lists the configuration keys that identify the CORS characteristics.
:rootdir: {docdir}/../..
:config-table-methods-column-header: annotation attribute
:allow-origins-method-name: value
:max-age-method-name: maxAge
:enabled-method-name: n/a

include::{rootdir}/includes/mp.adoc[]

== Contents

- <>
- <>
- <>
- <>
- <>
- <>
- <>

== Overview

include::{rootdir}/includes/cors.adoc[tag=cors-intro]
include::{rootdir}/includes/dependencies.adoc[]

[source,xml,subs="attributes+"]
----

    io.helidon.microprofile
    helidon-microprofile-cors

----

== Usage

Once you have planned how each of your resources should support CORS, you specify the CORS behavior in one of two ways:

* add `@CrossOrigin` annotations to the Java code for the resources, or
* add configuration.

You can do both. CORS configuration for a resource overrides any CORS settings declared using `@CrossOrigin` in the Java class for the resource.

== API

=== The `@CrossOrigin` Annotation

Adding CORS behavior to your Helidon MP application involves just a few simple steps.

For each resource class in your application:

. Identify the resources and sub-resources--in other words, the paths--declared in the resource class which you want to support CORS.
. For each of those resources and sub-resources which should support CORS:
.. Find or create a Java method annotated with `@OPTIONS` and with the correct `@Path`.
.. To that `@OPTIONS` Java method add a Helidon link:{mp-cors-javadoc-base-url}/io/helidon/microprofile/cors/CrossOrigin.html[`@CrossOrigin`] annotation that describes the cross-origin sharing you want for that resource.

[NOTE]
.Using @CrossOrigin Correctly
====
Use the `@CrossOrigin` annotation _only_ on methods which also have the `@OPTIONS` annotation. Remember that the `@CrossOrigin` settings apply to a given path and therefore to all Java resource methods which share that path.

Helidon MP aborts the server start-up if you use the `@CrossOrigin` annotation on a resource method other than an `@OPTIONS` method.

For an informal look at the reasons for applying the `@CrossOrigin` annotation to the `@OPTIONS` method, instead of another
method, see xref:{rootdir}/mp/cors/why-options.adoc[Why `@OPTIONS`?].
====

The xref:config-table[configuration table] below describes the attributes of the `@CrossOrigin` annotation.


== Configuration

You can define CORS behavior--and you or your users can override behavior declared in your code--using configuration.

For each resource you want to configure, add a section to `META-INF/microprofile-config.properties` file:

.General form of CORS configuration
[source,properties,subs="verbatim,quotes"]
----
cors.enabled= # <1>

# <2>
cors.paths._i_.path-pattern= # <3>
cors.paths._i_.allow-headers=
cors.paths._i_.max-age-seconds=
cors.paths._i_.allow-credentials=
cors.paths._i_.allow-origins=
cors.paths._i_.expose-headers=
cors.paths._i_.allow-methods=
cors.paths._i_.enabled= # <4>
----
<1> You can disable CORS processing for all resources by setting `cors.enabled` to `false`. Defaults to `true`.
<2> Add a block for each resource you want to configure.
The index `_i_` is an integer (0, 1, 2, etc).
<3> Specify the settings as needed to define the CORS behavior you want for that resource.
<4> The `enabled` setting lets you control whether the system uses that set of CORS configuration. Defaults to `true`.

The system uses the index `_i_`, not the position in the config file, to identify the settings for a particular resource.

Path patterns can be any expression accepted by the
link:{http-javadoc-base-url}/io/helidon/http/PathMatcher.html[`PathMatcher`] class.

NOTE: Helidon scans the cross-origin entries in index order (0, 1, 2, etc.) until it finds an entry that
matches an incoming request's path and HTTP method, so be sure to assign index values to the entries so Helidon will check them in the order you want. In particular, use lower index values for entries with more specific path patterns.

The table below describes the attributes on the `@CrossOrigin` annotation and the configuration keys
that map to the headers defined in the CORS protocol.
[#config-table]
include::{rootdir}/includes/cors.adoc[tag=cors-config-table]

== Examples

The link:{helidon-github-examples-url}/quickstarts/helidon-quickstart-mp[Helidon MP Quickstart application] allows users to:

* obtain greetings by sending `GET` requests to the `/greet` resource, and
* change the greeting message by sending a `PUT` request to the `/greet/greeting` resource.

The link:{helidon-github-examples-url}/microprofile/cors[Helidon MP CORS Example] shows the basic quickstart example enhanced for CORS.

The discussion below describes the changes in the application which:

* permit unrestricted sharing of the resource `/greet`, and
* restrict sharing of the resource `/greet/greeting` so that only the origins `\http://foo.com` and `\http://there.com` can change the greeting.

=== Adding Annotations

.Using annotations to declare CORS behavior
[source,java]
----
include::{sourcedir}/mp/cors/CorsSnippets.java[tag=snippet_1, indent=0]
----
<1> Existing `GreetResource` resource class with path `/greet`.
<2> Existing `@GET` method for resource `/greet`.
<3> Existing `@PUT` method for resource `/greet/greeting`.
<4> New `@OPTIONS` method for `/greet`. (Just like the `@GET` method `getDefaultMessage`, this `@OPTIONS` method does not have a `@Path` annotation; both "inherit" the class-level `@Path` setting `/greet`.) The `@CrossOrigin` annotation declares default cross-origin sharing which permits sharing via all HTTP methods to all origins.
<5> New `@OPTIONS` method for `/greet/greeting`. The `@CrossOrigin` annotation specifies sharing only via the `PUT` HTTP method and only to the two listed origins.

=== Adding Configuration
You could use the following configuration in place of using annotations to set up the same CORS behavior.

.Using configuration to set up the same CORS behavior
[source,properties]
----
cors.paths.0.path-pattern=/greet # <1>

cors.paths.1.path-pattern=/greet/greeting # <2>
cors.paths.1.allow-origins=https://foo.com,https://there.com
cors.paths.1.allow-methods=PUT
----
<1> Enables default CORS settings for the `/greet` resource.
<2> Sets up sharing for the `/greet/greeting` resource only via `PUT` requests and only from the specified origins.

Or, alternatively, the following configuration example augments the settings from the `@CrossOrigin` annotations in the code.

.Using configuration to augment or override declared CORS behavior
[source,properties]
----
cors.paths.0.path-pattern=/greet # <1>
cors.paths.0.allow-methods=GET
cors.paths.0.allow-origins=https://here.com,https://foo.com,https://there.com

cors.paths.1.path-pattern=/greet/greeting # <2>
cors.paths.1.allow-methods=PUT
cors.paths.1.allow-origins=https://foo.com
----
<1> Changes the declared settings to restrict cross-origin use of `/greet` to only `GET` and only from `foo.com` and `there.com`.
<2> Changes the settings for `/greet/greeting` from what they were declared; with this configuration, only the origin `foo.com` is permitted. (The declared setting also allowed `there.com`).



== Additional Information

include::{rootdir}/includes/cors.adoc[tag=cors-and-requested-uri-intro]
You can configure how the Helidon server handles these headers as described in the documentation for xref:{rootdir}/mp/server.adoc#_using_requested_uri_discovery[requested URI discovery].

include::{rootdir}/includes/cors.adoc[tag=cors-and-requested-uri-wrapup]

include::{rootdir}/includes/cors.adoc[tag=understanding-cors-support-in-services]

include::{rootdir}/includes/cors.adoc[tag=builtin-getting-started]

include::{rootdir}/includes/cors.adoc[tags=configuring-cors-for-builtin-services;!se-config-example]

The following example restricts sharing of

* the `/health` resource, provided by the health built-in service, to only the origin `\https://there.com`, and
* the `/metrics` resource, provided by the metrics built-in service, to only the origin `\https://foo.com`.

.Configuration which restricts sharing of the health and metrics resources
[source,properties]
----
cors.paths.0.path-pattern=/health
cors.paths.0.allow-origins=https://there.com
cors.paths.1.path-pattern=/metrics
cors.paths.1.allow-origins=https://foo.com
----

include::{rootdir}/includes/cors.adoc[tag=accessing-shared-resources-intro]
[source,bash]
----
mvn package
java -jar target/helidon-quickstart-mp.jar
----

[listing,bash]
.Console output
----
 ...
 2020.05.12 05:44:08 INFO io.helidon.microprofile.server.ServerCdiExtension Thread[main,5,main]: Server started on http://localhost:8080 (and all other host addresses) in 5280 milliseconds (since JVM startup).
 ...
----

include::{rootdir}/includes/cors.adoc[tag=accessing-shared-resources-main]




© 2015 - 2024 Weber Informatics LLC | Privacy Policy