Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CORS: support wildcard matching for AllowMethods and AllowHeaders #4168

Merged
merged 27 commits into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 27 additions & 9 deletions api/v1alpha1/cors_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

package v1alpha1

import metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
gwapiv1 "sigs.k8s.io/gateway-api/apis/v1"
)

// Origin is defined by the scheme (protocol), hostname (domain), and port of
// the URL used to access it. The hostname can be "precise" which is just the
Expand All @@ -29,18 +32,33 @@ type Origin string
// CORS defines the configuration for Cross-Origin Resource Sharing (CORS).
type CORS struct {
// AllowOrigins defines the origins that are allowed to make requests.
// +kubebuilder:validation:MinItems=1
zhaohuabing marked this conversation as resolved.
Show resolved Hide resolved
AllowOrigins []Origin `json:"allowOrigins,omitempty" yaml:"allowOrigins"`
//
// +optional
AllowOrigins []Origin `json:"allowOrigins,omitempty"`
zhaohuabing marked this conversation as resolved.
Show resolved Hide resolved

// AllowMethods defines the methods that are allowed to make requests.
// +kubebuilder:validation:MinItems=1
AllowMethods []string `json:"allowMethods,omitempty" yaml:"allowMethods"`
//
// +optional
zhaohuabing marked this conversation as resolved.
Show resolved Hide resolved
AllowMethods []gwapiv1.HTTPMethod `json:"allowMethods,omitempty"`

// AllowHeaders defines the headers that are allowed to be sent with requests.
AllowHeaders []string `json:"allowHeaders,omitempty" yaml:"allowHeaders,omitempty"`
//
// +optional
AllowHeaders []gwapiv1.HTTPHeaderName `json:"allowHeaders,omitempty"`

// ExposeHeaders defines the headers that can be exposed in the responses.
ExposeHeaders []string `json:"exposeHeaders,omitempty" yaml:"exposeHeaders,omitempty"`
//
// +optional
ExposeHeaders []gwapiv1.HTTPHeaderName `json:"exposeHeaders,omitempty"`

// MaxAge defines how long the results of a preflight request can be cached.
MaxAge *metav1.Duration `json:"maxAge,omitempty" yaml:"maxAge,omitempty"`
//
// +optional
MaxAge *metav1.Duration `json:"maxAge,omitempty"`

// AllowCredentials indicates whether a request can include user credentials
// like cookies, authentication headers, or TLS client certificates.
AllowCredentials *bool `json:"allowCredentials,omitempty" yaml:"allowCredentials,omitempty"`
//
zhaohuabing marked this conversation as resolved.
Show resolved Hide resolved
// +optional
AllowCredentials *bool `json:"allowCredentials,omitempty"`
}
6 changes: 3 additions & 3 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,52 @@ spec:
description: AllowHeaders defines the headers that are allowed
to be sent with requests.
items:
description: |-
HTTPHeaderName is the name of an HTTP header.

Valid values include:

* "Authorization"
* "Set-Cookie"

Invalid values include:

- ":method" - ":" is an invalid character. This means that HTTP/2 pseudo
headers are not currently supported by this type.
- "/invalid" - "/ " is an invalid character
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
type: array
allowMethods:
description: AllowMethods defines the methods that are allowed
to make requests.
items:
description: |-
HTTPMethod describes how to select a HTTP route by matching the HTTP
method as defined by
[RFC 7231](https://datatracker.ietf.org/doc/html/rfc7231#section-4) and
[RFC 5789](https://datatracker.ietf.org/doc/html/rfc5789#section-2).
The value is expected in upper case.

Note that values may be added to this enum, implementations
must ensure that unknown values will not cause a crash.

Unknown values here must result in the implementation setting the
Accepted Condition for the Route to `status: False`, with a
Reason of `UnsupportedValue`.
enum:
- GET
- HEAD
- POST
- PUT
- DELETE
- CONNECT
- OPTIONS
- TRACE
- PATCH
type: string
minItems: 1
type: array
allowOrigins:
description: AllowOrigins defines the origins that are allowed
Expand All @@ -288,12 +326,27 @@ spec:
minLength: 1
pattern: ^(\*|https?:\/\/(\*|(\*\.)?(([\w-]+\.?)+)?[\w-]+)(:\d{1,5})?)$
type: string
minItems: 1
type: array
exposeHeaders:
description: ExposeHeaders defines the headers that can be exposed
in the responses.
items:
description: |-
HTTPHeaderName is the name of an HTTP header.

Valid values include:

* "Authorization"
* "Set-Cookie"

Invalid values include:

- ":method" - ":" is an invalid character. This means that HTTP/2 pseudo
headers are not currently supported by this type.
- "/invalid" - "/ " is an invalid character
maxLength: 256
minLength: 1
pattern: ^[A-Za-z0-9!#$%&'*+\-.^_\x60|~]+$
type: string
type: array
maxAge:
Expand Down
43 changes: 35 additions & 8 deletions internal/gatewayapi/securitypolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,14 @@ func (t *Translator) translateSecurityPolicyForGateway(
}

func (t *Translator) buildCORS(cors *egv1a1.CORS) *ir.CORS {
var allowOrigins []*ir.StringMatch
var (
allowOrigins []*ir.StringMatch
irCORS *ir.CORS
)
irCORS = &ir.CORS{
MaxAge: cors.MaxAge,
AllowCredentials: cors.AllowCredentials != nil && *cors.AllowCredentials,
}

for _, origin := range cors.AllowOrigins {
if isWildcard(string(origin)) {
Expand All @@ -535,14 +542,34 @@ func (t *Translator) buildCORS(cors *egv1a1.CORS) *ir.CORS {
}
}

return &ir.CORS{
AllowOrigins: allowOrigins,
AllowMethods: cors.AllowMethods,
AllowHeaders: cors.AllowHeaders,
ExposeHeaders: cors.ExposeHeaders,
MaxAge: cors.MaxAge,
AllowCredentials: cors.AllowCredentials != nil && *cors.AllowCredentials,
allowMethods := make([]string, len(cors.AllowMethods))
for i, method := range cors.AllowMethods {
allowMethods[i] = string(method)
}

allowHeaders := make([]string, len(cors.AllowHeaders))
for i, header := range cors.AllowHeaders {
allowHeaders[i] = string(header)
}

exposeHeaders := make([]string, len(cors.ExposeHeaders))
for i, header := range cors.ExposeHeaders {
exposeHeaders[i] = string(header)
}

if len(allowOrigins) > 0 {
irCORS.AllowOrigins = allowOrigins
}
if len(allowMethods) > 0 {
irCORS.AllowMethods = allowMethods
}
if len(allowHeaders) > 0 {
irCORS.AllowHeaders = allowHeaders
}
if len(exposeHeaders) > 0 {
irCORS.ExposeHeaders = exposeHeaders
}
return irCORS
}

func isWildcard(s string) bool {
Expand Down
12 changes: 6 additions & 6 deletions site/content/en/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,12 +533,12 @@ _Appears in:_

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `allowOrigins` | _[Origin](#origin) array_ | true | AllowOrigins defines the origins that are allowed to make requests. |
| `allowMethods` | _string array_ | true | AllowMethods defines the methods that are allowed to make requests. |
| `allowHeaders` | _string array_ | true | AllowHeaders defines the headers that are allowed to be sent with requests. |
| `exposeHeaders` | _string array_ | true | ExposeHeaders defines the headers that can be exposed in the responses. |
| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | MaxAge defines how long the results of a preflight request can be cached. |
| `allowCredentials` | _boolean_ | true | AllowCredentials indicates whether a request can include user credentials<br />like cookies, authentication headers, or TLS client certificates. |
| `allowOrigins` | _[Origin](#origin) array_ | false | AllowOrigins defines the origins that are allowed to make requests. |
| `allowMethods` | _HTTPMethod array_ | false | AllowMethods defines the methods that are allowed to make requests. |
| `allowHeaders` | _[HTTPHeaderName](#httpheadername) array_ | false | AllowHeaders defines the headers that are allowed to be sent with requests. |
| `exposeHeaders` | _[HTTPHeaderName](#httpheadername) array_ | false | ExposeHeaders defines the headers that can be exposed in the responses. |
| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MaxAge defines how long the results of a preflight request can be cached. |
| `allowCredentials` | _boolean_ | false | AllowCredentials indicates whether a request can include user credentials<br />like cookies, authentication headers, or TLS client certificates. |



Expand Down
12 changes: 6 additions & 6 deletions site/content/zh/latest/api/extension_types.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,12 +533,12 @@ _Appears in:_

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `allowOrigins` | _[Origin](#origin) array_ | true | AllowOrigins defines the origins that are allowed to make requests. |
| `allowMethods` | _string array_ | true | AllowMethods defines the methods that are allowed to make requests. |
| `allowHeaders` | _string array_ | true | AllowHeaders defines the headers that are allowed to be sent with requests. |
| `exposeHeaders` | _string array_ | true | ExposeHeaders defines the headers that can be exposed in the responses. |
| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | true | MaxAge defines how long the results of a preflight request can be cached. |
| `allowCredentials` | _boolean_ | true | AllowCredentials indicates whether a request can include user credentials<br />like cookies, authentication headers, or TLS client certificates. |
| `allowOrigins` | _[Origin](#origin) array_ | false | AllowOrigins defines the origins that are allowed to make requests. |
| `allowMethods` | _HTTPMethod array_ | false | AllowMethods defines the methods that are allowed to make requests. |
| `allowHeaders` | _[HTTPHeaderName](#httpheadername) array_ | false | AllowHeaders defines the headers that are allowed to be sent with requests. |
| `exposeHeaders` | _[HTTPHeaderName](#httpheadername) array_ | false | ExposeHeaders defines the headers that can be exposed in the responses. |
| `maxAge` | _[Duration](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#duration-v1-meta)_ | false | MaxAge defines how long the results of a preflight request can be cached. |
| `allowCredentials` | _boolean_ | false | AllowCredentials indicates whether a request can include user credentials<br />like cookies, authentication headers, or TLS client certificates. |



Expand Down
Loading