CORS Middleware

This middleware provides a comprehensive, configurable implementation of the CORS (Cross Origin Resource Sharing) specification as oslo-supported python wsgi middleware.

Note

While this middleware supports the use of the * wildcard origin in the specification, this feature is not recommended for security reasons. It is provided to simplify basic use of CORS, practically meaning “I don’t care how this is used.” In an intranet setting, this could lead to leakage of data beyond the intranet and therefore should be avoided.

Quickstart

First, include the middleware in your application:

from oslo_middleware import cors

app = cors.CORS(your_wsgi_application)

Secondly, add as many allowed origins as you would like:

app.add_origin(allowed_origin='https://website.example.com:443',
               allow_credentials=True,
               max_age=3600,
               allow_methods=['GET','PUT','POST','DELETE'],
               allow_headers=['X-Custom-Header'],
               expose_headers=['X-Custom-Header'])

# ... add more origins here.

Configuration for oslo_config

A factory method has been provided to simplify configuration of your CORS domain, using oslo_config:

from oslo_middleware import cors
from oslo_config import cfg

app = cors.CORS(your_wsgi_application, cfg.CONF)

In your application’s config file, then include a default configuration block something like this:

[cors]
allowed_origin=https://website.example.com:443,https://website2.example.com:443
max_age=3600
allow_methods=GET,POST,PUT,DELETE
allow_headers=Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma,X-Custom-Header
expose_headers=Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma,X-Custom-Header

This middleware permits you to override the rules for multiple allowed_origin‘s. To express this in your configuration file, first begin with a [cors] group as above, into which you place your default configuration values. Then add as many additional configuration groups as necessary, naming them [cors.something] (each name must be unique). The purpose of the suffix to cors. is legibility, we recommend using a reasonable human-readable string:

[cors.ironic_webclient]
# CORS Configuration for a hypothetical ironic webclient, which overrides
# authentication
allowed_origin=https://ironic.example.com:443
allow_credentials=True

[cors.horizon]
# CORS Configuration for horizon, which uses global options.
allowed_origin=https://horizon.example.com:443

[cors.wildcard]
# CORS Configuration for the CORS specified domain wildcard, which only
# permits HTTP GET requests.
allowed_origin=*
allow_methods=GET

If your software requires specific headers or methods for proper operation, you may include these as latent properties. These will be evaluated in addition to any found in configuration:

from oslo_middleware import cors

app = cors.CORS(your_wsgi_application)
app.set_latent(allow_headers=['X-System-Header'],
               expose_headers=['X-System-Header'],
               allow_methods=['GET','PATCH'])

Configuration for pastedeploy

If your application is using pastedeploy, the following configuration block will add CORS support.:

[filter:cors]
paste.filter_factory = oslo_middleware.cors:filter_factory
allowed_origin=https://website.example.com:443,https://website2.example.com:443
max_age=3600
allow_methods=GET,POST,PUT,DELETE
allow_headers=Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma,X-Custom-Header
expose_headers=Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma,X-Custom-Header

If your application is using pastedeploy, but would also like to use the existing configuration from oslo_config in order to simplify the points of configuration, this may be done as follows.:

[filter:cors]
paste.filter_factory = oslo_middleware.cors:filter_factory
oslo_config_project = oslo_project_name

# Optional field, in case the program name is different from the project:
oslo_config_program = oslo_project_name-api

# This method also permits setting latent properties, for any origins set
# in oslo config.
latent_allow_headers=X-Auth-Token
latent_expose_headers=X-Auth-Token
latent_methods=GET,PUT,POST

Configuration Options

[DEFAULT]


[cors]

#
# From oslo.middleware.cors
#

# Indicate whether this resource may be shared with the domain
# received in the requests "origin" header. (list value)
#allowed_origin = <None>

# Indicate that the actual request can include user credentials
# (boolean value)
#allow_credentials = true

# Indicate which headers are safe to expose to the API. Defaults to
# HTTP Simple Headers. (list value)
#expose_headers = Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma

# Maximum cache age of CORS preflight requests. (integer value)
#max_age = 3600

# Indicate which methods can be used during the actual request. (list
# value)
#allow_methods = GET,POST,PUT,DELETE,OPTIONS

# Indicate which header field names may be used during the actual
# request. (list value)
#allow_headers = Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma


[cors.subdomain]

#
# From oslo.middleware.cors
#

# Indicate whether this resource may be shared with the domain
# received in the requests "origin" header. (list value)
#allowed_origin = <None>

# Indicate that the actual request can include user credentials
# (boolean value)
#allow_credentials = true

# Indicate which headers are safe to expose to the API. Defaults to
# HTTP Simple Headers. (list value)
#expose_headers = Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma

# Maximum cache age of CORS preflight requests. (integer value)
#max_age = 3600

# Indicate which methods can be used during the actual request. (list
# value)
#allow_methods = GET,POST,PUT,DELETE,OPTIONS

# Indicate which header field names may be used during the actual
# request. (list value)
#allow_headers = Content-Type,Cache-Control,Content-Language,Expires,Last-Modified,Pragma

Module Documentation

class oslo_middleware.cors.CORS(application, *args, **kwargs)

CORS Middleware.

This middleware allows a WSGI app to serve CORS headers for multiple configured domains.

For more information, see http://www.w3.org/TR/cors/

add_origin(allowed_origin, allow_credentials=True, expose_headers=None, max_age=None, allow_methods=None, allow_headers=None)

Add another origin to this filter.

Parameters:
  • allowed_origin – Protocol, host, and port for the allowed origin.
  • allow_credentials – Whether to permit credentials.
  • expose_headers – A list of headers to expose.
  • max_age – Maximum cache duration.
  • allow_methods – List of HTTP methods to permit.
  • allow_headers – List of HTTP headers to permit from the client.
Returns:

classmethod factory(global_conf, **local_conf)

factory method for paste.deploy

allowed_origin: Protocol, host, and port for the allowed origin. allow_credentials: Whether to permit credentials. expose_headers: A list of headers to expose. max_age: Maximum cache duration. allow_methods: List of HTTP methods to permit. allow_headers: List of HTTP headers to permit from the client.

process_response(response, request=None)

Check for CORS headers, and decorate if necessary.

Perform two checks. First, if an OPTIONS request was issued, let the application handle it, and (if necessary) decorate the response with preflight headers. In this case, if a 404 is thrown by the underlying application (i.e. if the underlying application does not handle OPTIONS requests, the response code is overridden.

In the case of all other requests, regular request headers are applied.

set_latent(allow_headers=None, allow_methods=None, expose_headers=None)

Add a new latent property for this middleware.

Latent properties are those values which a system requires for operation. API-specific headers, for example, may be added by an engineer so that they ship with the codebase, and thus do not require extra documentation or passing of institutional knowledge.

Parameters:
  • allow_headers – HTTP headers permitted in client requests.
  • allow_methods – HTTP methods permitted in client requests.
  • expose_headers – HTTP Headers exposed to clients.
exception oslo_middleware.cors.InvalidOriginError(origin)

Exception raised when Origin is invalid.

Table Of Contents

Previous topic

Healthcheck middleware plugins

Next topic

Middlewares and configuration

Project Source

This Page