This is an automated email from the ASF dual-hosted git repository.
rabbah pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git
The following commit(s) were added to refs/heads/master by this push:
new 0d8c663 update Access-Control-Allow-Headers CORS setting to enumerate
rather than wildcard (#4046)
0d8c663 is described below
commit 0d8c6631905c0385f1c99b3ff7899cd40fceafec
Author: Nick Mitchell <[email protected]>
AuthorDate: Sun Oct 21 16:15:32 2018 -0400
update Access-Control-Allow-Headers CORS setting to enumerate rather than
wildcard (#4046)
---
.../scala/whisk/core/controller/CorsSettings.scala | 52 ++++++++++++++++++++++
.../scala/whisk/core/controller/RestAPIs.scala | 8 +---
.../scala/whisk/core/controller/WebActions.scala | 13 ++++--
docs/rest_api.md | 2 +-
docs/webactions.md | 2 +-
tests/src/test/scala/services/HeadersTests.scala | 8 +++-
.../whisk/core/cli/test/WskWebActionsTests.scala | 2 +-
.../core/controller/test/WebActionsApiTests.scala | 2 +-
8 files changed, 73 insertions(+), 16 deletions(-)
diff --git
a/core/controller/src/main/scala/whisk/core/controller/CorsSettings.scala
b/core/controller/src/main/scala/whisk/core/controller/CorsSettings.scala
new file mode 100644
index 0000000..872000c
--- /dev/null
+++ b/core/controller/src/main/scala/whisk/core/controller/CorsSettings.scala
@@ -0,0 +1,52 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+package whisk.core.controller
+
+import akka.http.scaladsl.model.headers._
+import akka.http.scaladsl.model.HttpMethods.{DELETE, GET, HEAD, OPTIONS,
PATCH, POST, PUT}
+
+/**
+ * Defines the CORS settings for the REST APIs and Web Actions.
+ */
+protected[controller] object CorsSettings {
+
+ trait RestAPIs {
+ val allowOrigin = Defaults.allowOrigin
+ val allowHeaders = Defaults.allowHeaders
+ val allowMethods =
+ `Access-Control-Allow-Methods`(GET, DELETE, POST, PUT, HEAD)
+ }
+
+ trait WebActions {
+ val allowOrigin = Defaults.allowOrigin
+ val allowHeaders = Defaults.allowHeaders
+ val allowMethods = `Access-Control-Allow-Methods`(OPTIONS, GET, DELETE,
POST, PUT, HEAD, PATCH)
+ }
+
+ object Defaults {
+ val allowOrigin = `Access-Control-Allow-Origin`.*
+
+ val allowHeaders = `Access-Control-Allow-Headers`(
+ "Authorization",
+ "Origin",
+ "X-Requested-With",
+ "Content-Type",
+ "Accept",
+ "User-Agent")
+ }
+}
diff --git
a/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala
b/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala
index 5199889..fd842a0 100644
--- a/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/RestAPIs.scala
@@ -19,10 +19,8 @@ package whisk.core.controller
import akka.actor.ActorSystem
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport._
-import akka.http.scaladsl.model.HttpMethods.{DELETE, GET, HEAD, POST, PUT}
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.model.Uri
-import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.server.directives.AuthenticationDirective
import akka.http.scaladsl.server.{Directives, Route}
import akka.stream.ActorMaterializer
@@ -149,11 +147,7 @@ protected[controller] object RestApiCommons {
* A trait for wrapping routes with headers to include in response.
* Useful for CORS.
*/
-protected[controller] trait RespondWithHeaders extends Directives {
- val allowOrigin = `Access-Control-Allow-Origin`.*
- val allowHeaders = `Access-Control-Allow-Headers`("*")
- val allowMethods =
- `Access-Control-Allow-Methods`(GET, DELETE, POST, PUT, HEAD)
+protected[controller] trait RespondWithHeaders extends Directives with
CorsSettings.RestAPIs {
val sendCorsHeaders = respondWithHeaders(allowOrigin, allowHeaders,
allowMethods)
}
diff --git
a/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
b/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
index 978dc24..eb6c5c2 100644
--- a/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
+++ b/core/controller/src/main/scala/whisk/core/controller/WebActions.scala
@@ -40,7 +40,7 @@ import akka.http.scaladsl.model.headers.`Timeout-Access`
import akka.http.scaladsl.model.ContentType
import akka.http.scaladsl.model.ContentTypes
import akka.http.scaladsl.model.FormData
-import akka.http.scaladsl.model.HttpMethods.{DELETE, GET, HEAD, OPTIONS,
PATCH, POST, PUT}
+import akka.http.scaladsl.model.HttpMethods.{OPTIONS}
import akka.http.scaladsl.model.HttpCharsets
import akka.http.scaladsl.model.HttpResponse
import spray.json._
@@ -353,7 +353,12 @@ protected[core] object WhiskWebActionsApi extends
Directives {
headers.filter(_.lowercaseName != `Content-Type`.lowercaseName)
}
-trait WhiskWebActionsApi extends Directives with ValidateRequestSize with
PostActionActivation with CustomHeaders {
+trait WhiskWebActionsApi
+ extends Directives
+ with ValidateRequestSize
+ with PostActionActivation
+ with CustomHeaders
+ with CorsSettings.WebActions {
services: WhiskServices =>
/** API path invocation path for posting activations directly through the
host. */
@@ -380,10 +385,10 @@ trait WhiskWebActionsApi extends Directives with
ValidateRequestSize with PostAc
private lazy val packagePrefix = pathPrefix("default".r | EntityName.REGEX.r)
private val defaultCorsBaseResponse =
- List(`Access-Control-Allow-Origin`.*,
`Access-Control-Allow-Methods`(OPTIONS, GET, DELETE, POST, PUT, HEAD, PATCH))
+ List(allowOrigin, allowMethods)
private val defaultCorsWithAllowHeader = {
- defaultCorsBaseResponse :+ `Access-Control-Allow-Headers`("*")
+ defaultCorsBaseResponse :+ allowHeaders
}
private def defaultCorsResponse(headers: Seq[HttpHeader]): List[HttpHeader]
= {
diff --git a/docs/rest_api.md b/docs/rest_api.md
index 28932be..88d9790 100644
--- a/docs/rest_api.md
+++ b/docs/rest_api.md
@@ -82,7 +82,7 @@ curl -u USERNAME:PASSWORD
https://openwhisk.ng.bluemix.net/api/v1/namespaces/whi
In this example the authentication was passed using the `-u` flag, you can
pass this value also as part of the URL as `https://$AUTH@{APIHOST}`
-The OpenWhisk API supports request-response calls from web clients. OpenWhisk
responds to `OPTIONS` requests with Cross-Origin Resource Sharing headers.
Currently, all origins are allowed (that is, Access-Control-Allow-Origin is
"`*`"), the standard set of methods are allowed (that is,
Access-Control-Allow-Methods is "`GET, DELETE, POST, PUT, HEAD`"), and
Access-Control-Allow-Headers yields "`*`".
+The OpenWhisk API supports request-response calls from web clients. OpenWhisk
responds to `OPTIONS` requests with Cross-Origin Resource Sharing headers.
Currently, all origins are allowed (that is, Access-Control-Allow-Origin is
"`*`"), the standard set of methods are allowed (that is,
Access-Control-Allow-Methods is "`GET, DELETE, POST, PUT, HEAD`"), and
Access-Control-Allow-Headers yields "`Authorization, Origin, X-Requested-With,
Content-Type, Accept, User-Agent`".
**Attention:** Because OpenWhisk currently supports only one key per
namespace, it is not recommended to use CORS beyond simple experiments. Use
[Web Actions](webactions.md) or [API Gateway](apigateway.md) to expose your
actions to the public and not use the OpenWhisk authorization key for client
applications that require CORS.
diff --git a/docs/webactions.md b/docs/webactions.md
index 547fcba..d5c71c8 100644
--- a/docs/webactions.md
+++ b/docs/webactions.md
@@ -450,7 +450,7 @@ if it is present in the HTTP request. Otherwise, a default
value is generated as
```
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: OPTIONS, GET, DELETE, POST, PUT, HEAD, PATCH
-Access-Control-Allow-Headers: *
+Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With,
Content-Type, Accept, User-Agent
```
Alternatively, OPTIONS requests can be handled manually by a web action. To
enable this option add a
diff --git a/tests/src/test/scala/services/HeadersTests.scala
b/tests/src/test/scala/services/HeadersTests.scala
index c0485de..0bb3c18 100644
--- a/tests/src/test/scala/services/HeadersTests.scala
+++ b/tests/src/test/scala/services/HeadersTests.scala
@@ -64,7 +64,13 @@ class HeadersTests extends FlatSpec with Matchers with
ScalaFutures with WskActo
val creds = BasicHttpCredentials(whiskAuth.fst, whiskAuth.snd)
val allMethods = Some(Set(DELETE.name, GET.name, POST.name, PUT.name))
val allowOrigin = `Access-Control-Allow-Origin`.*
- val allowHeaders = `Access-Control-Allow-Headers`("*")
+ val allowHeaders = `Access-Control-Allow-Headers`(
+ "Authorization",
+ "Origin",
+ "X-Requested-With",
+ "Content-Type",
+ "Accept",
+ "User-Agent")
val url =
Uri(s"$controllerProtocol://${WhiskProperties.getBaseControllerAddress()}")
def request(method: HttpMethod, uri: Uri, headers: Option[Seq[HttpHeader]] =
None): Future[HttpResponse] = {
diff --git a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
b/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
index 700f87e..493ce0a 100644
--- a/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
+++ b/tests/src/test/scala/whisk/core/cli/test/WskWebActionsTests.scala
@@ -204,7 +204,7 @@ class WskWebActionsTests extends TestHelpers with
WskTestHelpers with RestUtil w
response.statusCode shouldBe 200
response.header("Access-Control-Allow-Origin") shouldBe "*"
response.header("Access-Control-Allow-Methods") shouldBe "OPTIONS, GET,
DELETE, POST, PUT, HEAD, PATCH"
- response.header("Access-Control-Allow-Headers") shouldBe "*"
+ response.header("Access-Control-Allow-Headers") shouldBe "Authorization,
Origin, X-Requested-With, Content-Type, Accept, User-Agent"
response.header("Location") shouldBe null
response.header("Set-Cookie") shouldBe null
}
diff --git
a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
index deee6fe..e4bb43b 100644
--- a/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
+++ b/tests/src/test/scala/whisk/core/controller/test/WebActionsApiTests.scala
@@ -1502,7 +1502,7 @@ trait WebActionsApiBaseTests extends ControllerTestCommon
with BeforeAndAfterEac
if (testHeader.name == `Access-Control-Request-Headers`.name) {
header("Access-Control-Allow-Headers").get.toString shouldBe
"Access-Control-Allow-Headers: x-custom-header"
} else {
- header("Access-Control-Allow-Headers").get.toString shouldBe
"Access-Control-Allow-Headers: *"
+ header("Access-Control-Allow-Headers").get.toString shouldBe
"Access-Control-Allow-Headers: Authorization, Origin, X-Requested-With,
Content-Type, Accept, User-Agent"
}
}
}