diff --git a/docs/includes/cors.adoc b/docs/includes/cors.adoc index 585e9aef6a1..7c9912ceb12 100644 --- a/docs/includes/cors.adoc +++ b/docs/includes/cors.adoc @@ -24,13 +24,16 @@ ifndef::h1-prefix[:h1-prefix: SE] //Contains content that is shared between multiple CORS pages. :keywords: helidon, java, cors, se :basic-table-intro: -:config-table-methods-column-header: +:config-table-methods-column-header: builder method :cors-config-key-explanation: +:allow-origins-method-name: allowOrigins +:max-age-method-name: maxAgeSeconds +:enabled-method-name: enabled = CORS Shared content // tag::cors-intro[] -The CORS protocol helps developers control if and how REST resources served by their applications can be shared across origins. +The link:https://www.w3.org/TR/cors[cross-origin resource sharing (CORS) protocol] helps developers control if and how REST resources served by their applications can be shared across origins. Helidon {flavor-uc} includes an implementation of CORS that you can use to add CORS behavior to the services you develop. You can define your application's CORS behavior programmatically using the Helidon CORS API alone, or together with configuration. @@ -123,56 +126,58 @@ endif::[] // To exclude the second column -- the config keys -- and the text that describes it, define // cors-config-table-exclude-keys in the including file. The value does not matter. // -// To customize the text that explains the first column, set config-table-methods-column-explainer -// to the text you want inserted. -// // To customize the column heading for the first column, set config-table-methods-column-header to // the header you want used. // +// You can also customize the following names for methods (on the builder) or annotation attribute names (because the builder and annotation names differ in these cases): +// allow-origins-method-name +// max-age-method-name +// enabled-method-name +// // tag::cors-config-table[] ifndef::cors-config-table-exclude-methods+cors-config-table-exclude-keys[] -[width="100%",options="header",cols="4*"] +[width="100%",options="header",cols="6*"] endif::[] ifdef::cors-config-table-exclude-methods[] -[width="100%",options="header",cols="3*"] +[width="100%",options="header",cols="5*"] endif::[] ifdef::cors-config-table-exclude-keys[] -[width="100%",options="header",cols="3*"] +[width="100%",options="header",cols="5*"] endif::[] |==================== ifndef::cors-config-table-exclude-methods[| {config-table-methods-column-header} ] -ifndef::cors-config-table-exclude-keys[| Configuration Key] -| Default | CORS Header Name +ifndef::cors-config-table-exclude-keys[| config key] +| type | default | description | CORS header name ifndef::cors-config-table-exclude-methods[|`allowCredentials`] ifndef::cors-config-table-exclude-keys[|`allow-credentials`] -|`false`|`Access-Control-Allow-Credentials` +|boolean |`false`|Sets the allow credentials flag. |`Access-Control-Allow-Credentials` ifndef::cors-config-table-exclude-methods[|`allowHeaders`] ifndef::cors-config-table-exclude-keys[|`allow-headers`] -|`["*"]`|`Access-Control-Allow-Headers` +|string[]|`*`|Sets the allowed headers.|`Access-Control-Allow-Headers` ifndef::cors-config-table-exclude-methods[|`allowMethods`] ifndef::cors-config-table-exclude-keys[|`allow-methods`] -|`["*"]`|`Access-Control-Allow-Methods` +|string[]|`*`|Sets the allowed methods. |`Access-Control-Allow-Methods` -ifndef::cors-config-table-exclude-methods[|`allowOrigins`] +ifndef::cors-config-table-exclude-methods[|`{allow-origins-method-name}`] ifndef::cors-config-table-exclude-keys[|`allow-origins`] -|`["*"]`|`Access-Control-Allow-Origins` +|string[]|`*`| Sets the allowed origins.|`Access-Control-Allow-Origins` ifndef::cors-config-table-exclude-methods[|`exposeHeaders`] ifndef::cors-config-table-exclude-keys[|`expose-headers`] -|`none`|`Access-Control-Expose-Headers` +|string[] | |Sets the expose headers. |`Access-Control-Expose-Headers` -ifndef::cors-config-table-exclude-methods[|`maxAgeSeconds`] -ifndef::cors-config-table-exclude-keys[|`max-age`] -|`3600`|`Access-Control-Max-Age` +ifndef::cors-config-table-exclude-methods[|`{max-age-method-name}`] +ifndef::cors-config-table-exclude-keys[|`max-age-seconds`] +|long |`3600`|Sets the maximum age. |`Access-Control-Max-Age` -ifndef::cors-config-table-exclude-methods[|`enabled`] +ifndef::cors-config-table-exclude-methods[|`{enabled-method-name}`] ifndef::cors-config-table-exclude-keys[|`enabled`] -|`true`|n/a| +|boolean|`true`|Sets whether this config should be enabled or not.|n/a| |==================== If the cross-origin configuration is disabled (`enabled` = false), then the Helidon CORS implementation ignores the cross-origin configuration entry. @@ -244,14 +249,13 @@ matches an incoming request's path pattern and HTTP method. // end::mapped-config[] // tag::understanding-cors-support-in-services[] -== Understanding CORS Support in Helidon Services +=== Using CORS Support in Built-in Helidon Services include::{rootdir}/includes/pages.adoc[] -Helidon lets you easily include xref:{health-page}[health], xref:{metrics-page}[metrics], and - xref:{openapi-page}[OpenAPI] services in your Helidon application. -These services add endpoints to your application so that clients can retrieve information about it. -As with the application endpoints you write, these endpoints represent resources that can be shared across origins. +Several built-in Helidon services--xref:{health-page}[health], xref:{metrics-page}[metrics], and +xref:{openapi-page}[OpenAPI]--have integrated CORS support. +You can include these services in your application and control how those resources can be shared across origins. For example, several websites related to OpenAPI run a web application in your browser. You provide the URL for your application to the browser application. @@ -279,7 +283,7 @@ to your own endpoints. // end::understanding-cors-support-in-services[] // tag::builtin-getting-started[] -=== Built-in Services with CORS +==== Built-in Services with CORS include::{rootdir}/includes/pages.adoc[] @@ -307,6 +311,7 @@ ifdef::se-flavor[dependency and including the service in your application's rout ifndef::se-flavor[dependency.] In your application's configuration file, the configuration for each service appears under its own key. +[%autowidth] |==== | Helidon Service Documentation | Configuration Key | xref:{health-page}[health] | `health` @@ -329,7 +334,7 @@ use configuration to control whether and how each of the built-in services works ifdef::se-flavor[] Your application can pass configuration to the builder for each built-in service. endif::[] -For the health, metrics, and OpenAPI services, your configuration can include a section for CORS. +In the configuration for the health, metrics, and OpenAPI services, you can add a section for CORS. // Tag the following example so we can exclude it from MP which supplies its own complete example. // tag::se-config-example[] @@ -358,30 +363,30 @@ HealthSupport health = HealthSupport.builder() // end::se-code-changes-for-builtin-services-config[] -You have full control over the CORS configuration for a built-in Helidon service. Use a basic CORS config section +You have full control over the CORS configuration for a built-in Helidon service. Use a CORS config section as described in ifdef::se-flavor[] -xref:{rootdir}/se/cors.adoc#using-config-from-app[Using Configuration for CORS]. +xref:#using-config-from-app[Using Configuration for CORS]. endif::[] ifndef::se-flavor[] -xref:{rootdir}/mp/cors/configuration-with-cors-mp.adoc[Using Configuration with CORS in Helidon MP]. +xref:#config-table[the configuration table]. endif::[] // end::configuring-cors-for-builtin-services[] // tag::accessing-shared-resources-intro[] -=== Accessing the Shared Resources +==== Accessing the Shared Resources If you have edited the Helidon {flavor-uc} QuickStart application as described in the previous topics and saved your changes, you can build and run the application. Once you do so you can execute `curl` commands to demonstrate the behavior changes in the metric and health services with the addition of the CORS functionality. Note the addition of the `Origin` header value in the `curl` commands, and the `Access-Control-Allow-Origin` in the successful responses. -=== Build and Run the Application +===== Build and Run the Application Build and run the QuickStart application as usual. // end::accessing-shared-resources-intro[] // tag::accessing-shared-resources-main[] -==== Retrieve Metrics +===== Retrieve Metrics The metrics service rejects attempts to access metrics on behalf of a disallowed origin. [source,bash] ---- @@ -417,7 +422,7 @@ content-length: 6065 base_classloader_loadedClasses_count 3568 ---- -==== Retrieve Health +===== Retrieve Health The health service rejects requests from origins not specifically approved. [source,bash] diff --git a/docs/mp/cors/configuration-with-cors-mp.adoc b/docs/mp/cors/configuration-with-cors-mp.adoc deleted file mode 100644 index 9686d9210ec..00000000000 --- a/docs/mp/cors/configuration-with-cors-mp.adoc +++ /dev/null @@ -1,82 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2020, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= Using Configuration with CORS in Helidon MP -:toc: -:toc-placement: preamble -:description: Helidon MP CORS Configuration -:keywords: helidon, java, cors, mp, microprofile, configuration -:mapped-config-top-key: cors -:mapped-config-id-callout: The unique identifier for this mapped CORS config section must be `cors`. -:config-table-methods-column-explainer: the annotation parameters -:config-table-methods-column-header: Annotation Parameter -:basic-table-intro: The table below lists the parameters for the `@CrossOriginConfig` annotation and the configuration keys that identify the CORS characteristics. -:rootdir: {docdir}/../.. -:cors-config-key-explanation: - -include::{rootdir}/includes/mp.adoc[] - -Your application code establishes the CORS behavior of your endpoints using the `@CrossOrigin` annotation. -You and your users can override that behavior, as well as the CORS behavior of the built-in services, -using MicroProfile configuration. - -include::{rootdir}/includes/cors.adoc[tag=cors-configuration-formats-intro, leveloffset=-1] -include::{rootdir}/includes/cors.adoc[tag=basic-cross-origin-config, leveloffset=-1] - -=== Understanding the Mapped Cross-Origin Configuration Format - -In Helidon MP, you use -the mapped cross-origin configuration format. - -// We want to use -// include::{rootdir}/includes/cors.adoc[tag=mapped-config] -// and assign an attribute for the callout 1 text. But because the MP value uses backticks for monospaced -// text, we'd have to be a little clever in the original callout. And that cleverness works when -// the document is rendered in our editors, and even when using asciidoctor to HTML, but not -// to our site. -include::{rootdir}/includes/cors.adoc[tag=mapped-config-prefix] -<1> The unique identifier for this mapped CORS config section must be `cors`. -include::{rootdir}/includes/cors.adoc[tag=mapped-config-suffix] - -== Specifying Override Values in Configuration -In configuration, you can specify the same CORS-related attributes that you specify using the `@CrossOrigin` annotation. - -The following example shows how you can express configuration similar to that shown -previously using the mapped cross-origin configuration format. -Here, the example uses properties-file syntax -in your application's `META-INF/microprofile-config.properties` file. Note that the top-level config key -must be `cors`. - -[source,properties] ----- -cors.paths.0.path-pattern = /greeting -cors.paths.0.allow-origins = http://foo.com, http://there.com, http://other.com -cors.paths.0.allow-methods = PUT, DELETE -cors.paths.1.path-pattern = / -cors.paths.1.allow-methods = GET, HEAD, OPTIONS, POST ----- - -NOTE: 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. xref:support-in-builtin-services.adoc[Learn more]. - -* See the Helidon CORS support in action by building and running the link:{helidon-github-tree-url}/examples/microprofile/cors[CORS example]. diff --git a/docs/mp/cors/cors.adoc b/docs/mp/cors/cors.adoc new file mode 100644 index 00000000000..0690f91ed24 --- /dev/null +++ b/docs/mp/cors/cors.adoc @@ -0,0 +1,249 @@ +/////////////////////////////////////////////////////////////////////////////// + + Copyright (c) 2022 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[] + +== ToC + +- <> +- <> +- <> +- <> +- <> +- <> +- <> + +== 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 reach resource class in your application: + +. Identify the resources and subresources--in other words, the paths--declared in the resource class which you want to support CORS. +. For each of those resources and subresources 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:{webserver-javadoc-base-url}/io/helidon/webserver/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-tree-url}/examples/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-tree-url}/examples/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] +---- +@Path("/greet") +public class GreetResource { // <1> + + @GET + public JsonObject getDefaultMessage() {...} // <2> + + @Path("/greeting") + @PUT + public Response updateGreeting(JsonObject jsonObject) {...} // <3> + + @OPTIONS + @CrossOrigin() + public void optionsForRetrievingUnnamedGreeting() {} // <4> + + @OPTIONS + @Path("/greeting") + @CrossOrigin({"http://foo.com", "http://there.com"}, + allowMethods = {HttpMethod.PUT}) + public void optionsForUpdatingGreeting() {} // <5> +} +---- +<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=http://foo.com,http://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=http://here.com,http://foo.com,http://there.com + +cors.paths.1.path-patterh=/greet/greeting # <2> +cors.paths.1.allow-methods=PUT +cors.paths.1.allow-origins=http://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=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;!se-code-changes-for-builtin-services-config] + +The following example restricts sharing of + +* the `/health` resource, provided by the health built-in service, to only the origin `\http://there.com`, and +* the `/metrics` resource, provided by the metrics built-in service, to only the origin `\http://foo.com`. + +.Configuration which restricts sharing of the health and metrics resources +[source,properties] +---- +health.cors.allow-origins=http://there.com + +metrics.cors.allow-origins=http://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] +---- + ... + 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] \ No newline at end of file diff --git a/docs/mp/cors/introduction.adoc b/docs/mp/cors/introduction.adoc deleted file mode 100644 index da76bea0628..00000000000 --- a/docs/mp/cors/introduction.adoc +++ /dev/null @@ -1,43 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2020, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= About CORS in Helidon MP -:toc: -:toc-placement: preamble -:description: Introduction to CORS in Helidon MP -:keywords: helidon, java, cors, mp, microprofile, cross-origin resource sharing -:rootdir: {docdir}/../.. - -include::{rootdir}/includes/mp.adoc[] - -link:https://www.w3.org/TR/cors[Cross-origin resource sharing] (CORS) support in Helidon MP provides a flexible -mechanism that allows a Helidon MP application to control how another web application can access its resources, -even if that web application is served from a different domain. - - -== Overview - -include::{rootdir}/includes/cors.adoc[tag=cors-intro] - -== Next Steps -To introduce CORS into your Helidon MP application, do any or all of the following: - -* Modify your code using the Helidon MP CORS API. xref:using-cors.adoc[Learn more]. -* Use configuration to allow users to override the CORS settings established in your application code. xref:configuration-with-cors-mp.adoc[Learn more]. -* Update your application to include any of the built-in Helidon services that automatically -support CORS. xref:support-in-builtin-services.adoc[Learn more]. diff --git a/docs/mp/cors/support-in-builtin-services.adoc b/docs/mp/cors/support-in-builtin-services.adoc deleted file mode 100644 index 141c911d9e9..00000000000 --- a/docs/mp/cors/support-in-builtin-services.adoc +++ /dev/null @@ -1,64 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2020, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= Using CORS in Helidon MP Built-in Services -:toc: -:toc-placement: preamble -:description: Helidon MP CORS Support in Built-in Services -:keywords: helidon, java, cors, mp, services -:cors-config-table-exclude-methods: -:rootdir: {docdir}/../.. - -include::{rootdir}/includes/mp.adoc[] - -Several built-in Helidon services -- health, metrics, and OpenAPI -- have integrated CORS support. -You can include these services in your application and control their CORS behavior. - -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;!se-code-changes-for-builtin-services-config] - -The following example restricts sharing of - -* the `/health` resource, provided by the health built-in service, to only the origin `\http://there.com`, and -* the `/metrics` resource, provided by the metrics built-in service, to only the origin `\http://foo.com`. - -[source,hocon] ----- -health: - cors: - allow-origins: [http://there.com] -metrics: - cors: - allow-origins: [http://foo.com] ----- - -include::{rootdir}/includes/cors.adoc[tag=accessing-shared-resources-intro] - -[source,bash] ----- -mvn package -java -jar target/helidon-quickstart-mp.jar ----- - -[source, listing] ----- -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] diff --git a/docs/mp/cors/using-cors.adoc b/docs/mp/cors/using-cors.adoc deleted file mode 100644 index 55e8d80ff4b..00000000000 --- a/docs/mp/cors/using-cors.adoc +++ /dev/null @@ -1,121 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// - - Copyright (c) 2020, 2022 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. - -/////////////////////////////////////////////////////////////////////////////// - -= Using the Helidon MP CORS API -:toc: -:toc-placement: preamble -:description: Using the Helidon MP CORS API -:keywords: helidon, java, cors, mp, microprofile -:rootdir: {docdir}/../.. -:feature-name: CORS - -include::{rootdir}/includes/mp.adoc[] - -To enable CORS behavior for a resource in your Helidon MP application, you simply add the Helidon MP `@CrossOrigin` -annotation to a particular method in your resource class. - -include::{rootdir}/includes/dependencies.adoc[] - -[source,xml,subs="attributes+"] ----- - - io.helidon.microprofile - helidon-microprofile-cors - ----- - -== Understanding the `@CrossOrigin` Annotation -You set up CORS in Helidon MP using the link:{mp-cors-javadoc-base-url}/io/helidon/microprofile/cors/CrossOrigin.html[`@CrossOrigin`] annotation. - -The following example of the `@CrossOrigin` annotation allows the resource associated with it to be shared with the origins `\http://foo.bar` and `\http://bar.foo` -using `DELETE` or `PUT`, and permits requests to include the non-standard headers `X-foo` and `X-bar`. - -[source,java] ----- -@CrossOrigin(value = {"http://foo.bar", "http://bar.foo"}, - allowHeaders = {"X-foo", "X-bar"}, - allowMethods = {HttpMethod.DELETE, HttpMethod.PUT}) ----- - -== Getting Started -To add CORS support to your Helidon MP application: - -1. Determine the type of cross-origin resource sharing you want to allow - for each endpoint in your application. -2. Add a dependency on the Helidon {flavor-uc} CORS <> to your Maven `pom.xml` file. - -3. Edit each JAX-RS resource class in your application to add the desired CORS behavior as described in the following sections. - - - -== Adding CORS Support to Your Helidon MP Application -Adding CORS behavior to your Helidon MP application involves three simple steps: - -For reach resource class in your application: - -. Identify the resources and sub resources--in other words, the paths--supported in each. -. For each of those resources and sub resources make sure you have a Java method annotated with -`@OPTIONS` and with the correct `@Path`. Create these methods for each resource (for each path) if you do not already have them. -. To each of those `@OPTIONS` methods add a `@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 a resource method other than an `@OPTIONS` method has the `@CrossOrigin` annotation. -==== - -The Helidon MP CORS implementation automatically uses the `@CrossOrigin` annotation you add to each `@OPTIONS` method to -enforce cross-origin sharing behavior for the resource identified by that method's `@Path` annotation. - -For an informal look at the reasons for applying the `@CrossOrigin` annotation to the `@OPTIONS` method, instead of another -method, see xref:hide-why-options.adoc[Why `@OPTIONS`?]. - -== Sample Application Using the `@CrossOrigin` Annotation - -In the link:{helidon-github-tree-url}/examples/quickstarts/helidon-quickstart-mp[Helidon MP Quickstart application] -you can change the greeting by sending a `PUT` request to the `/greet/greeting` resource. -The example below extends the Helidon MP QuickStart application (the greeting app) to: - -* Permit unrestricted sharing of the resource that returns greetings, and -* Restrict sharing of the resource that -updates the greeting so that only the origins `\http://foo.com` and `\http://there.com` can change the greeting. - -[source,java] ----- -@OPTIONS -@CrossOrigin() // <1> -public void options() {} - -@OPTIONS -@Path("/greeting") -@CrossOrigin(allowMethods = {"PUT"}, allowOrigins = {"http://foo.com", "http://there.com"}) // <2> -public void optionsForGreeting() {} ----- -<1> Uses the default cross-origin sharing, which permits sharing via all HTTP methods to all origins. -<2> Specifies sharing only via the `PUT` HTTP method and only to the two listed origins. - -== Next steps - -* Use MicroProfile configuration to override the CORS behavior set in -the application code. xref:configuration-with-cors-mp.adoc[Learn more]. - -* See the Helidon CORS support in action by building and running the - link:{helidon-github-tree-url}/examples/microprofile/cors[CORS example]. diff --git a/docs/mp/cors/hide-why-options.adoc b/docs/mp/cors/why-options.adoc similarity index 100% rename from docs/mp/cors/hide-why-options.adoc rename to docs/mp/cors/why-options.adoc diff --git a/docs/mp/introduction/introduction.adoc b/docs/mp/introduction/introduction.adoc index 58c190efb8c..2e47e64fbb5 100644 --- a/docs/mp/introduction/introduction.adoc +++ b/docs/mp/introduction/introduction.adoc @@ -70,7 +70,7 @@ In addition to MicroProfile support, Helidon MP provides additional CDI extensio //CORS [CARD] .CORS -[icon=share,link=../cors/introduction.adoc] +[icon=share,link=../cors/cors.adoc] -- Add support for CORS to your application using a Helidon module. -- diff --git a/docs/se/cors.adoc b/docs/se/cors.adoc index 8938c10f3ed..1402f5cb33e 100644 --- a/docs/se/cors.adoc +++ b/docs/se/cors.adoc @@ -24,7 +24,7 @@ :feature-name: CORS :cors-config-key-explanation: , identified by a configuration key of your choosing, :mapped-config-top-key: my-cors -:cors-config-table-exclude-methods: +:config-table-methods-column-header: builder method :!cors-config-table-exclude-keys: :basic-table-intro: The table below lists the configuration keys that identify the CORS characteristics. :rootdir: {docdir}/.. @@ -94,8 +94,8 @@ which origins are allowed to share via which HTTP methods, etc. Each of these classes has an associated builder that you use in constructing instances of the class. -The table below describes the methods on the `CrossOriginConfig.Builder` class -that map to the headers defined in the CORS protocol. +The table below describes the methods on the `CrossOriginConfig.Builder` class and the configuration keys +that map to the headers defined in the CORS protocol. (A later section discusses xref:Configuration[configuration].) include::{rootdir}/includes/cors.adoc[tag=cors-config-table] @@ -185,7 +185,7 @@ include::{rootdir}/includes/cors.adoc[tag=mapped-config-prefix] <1> Assigns a unique identifier for this mapped CORS config section. include::{rootdir}/includes/cors.adoc[tag=mapped-config-suffix] -[[using-config-from-app]] +[#using-config-from-app] === 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 <> @@ -249,13 +249,12 @@ For a complete example, see {helidon-github-tree-url}/examples/cors[Helidon SE C == Additional Information -Several built-in Helidon services -- health, metrics, and OpenAPI -- have integrated CORS support. -You can include these services in your application and control their CORS behavior. - include::{rootdir}/includes/cors.adoc[tag=understanding-cors-support-in-services] include::{rootdir}/includes/cors.adoc[tag=builtin-getting-started] -=== Controlling CORS for Built-in Services Using the API +==== Controlling CORS for Built-in Services + +===== Using the API Although services such as health, metrics, and OpenAPI are built into Helidon, to use them your application must create instances of the services and then use those instances in building your application's routing rules. @@ -300,8 +299,8 @@ the `RestServiceSetting.Builder` (which assigns common settings such as the CORS <3> Use the `RestServiceSetting.Builder` in preparing the `MetricsSupport` service. <4> Use the `MetricsSupport` object in creating the routing rules. -include::{rootdir}/includes/cors.adoc[tag=configuring-cors-for-builtin-services] -include::{rootdir}/includes/cors.adoc[tag=accessing-shared-resources-intro, leveloffset=+1] +include::{rootdir}/includes/cors.adoc[tag=configuring-cors-for-builtin-services,leveloffset=+2] +include::{rootdir}/includes/cors.adoc[tag=accessing-shared-resources-intro] [source,bash] ---- diff --git a/docs/sitegen.yaml b/docs/sitegen.yaml index 84ae481dcb1..75776e6ca17 100644 --- a/docs/sitegen.yaml +++ b/docs/sitegen.yaml @@ -353,17 +353,12 @@ backend: - "cdi-jedis.adoc" - "cdi-oci-objectstorage.adoc" - "cdi-jta.adoc" - - type: "MENU" + - type: "PAGE" title: "CORS" - dir: "cors" + source: "cors/cors.adoc" glyph: type: "icon" value: "share" - sources: - - "introduction.adoc" - - "using-cors.adoc" - - "configuration-with-cors-mp.adoc" - - "support-in-builtin-services.adoc" - type: "PAGE" title: "Fault Tolerance" source: "fault-tolerance.adoc"