Added CORS support to Neutron

This adds the CORS support middleware to Neutron, allowing a deployer
to optionally configure rules under which a javascript client may
break the single-origin policy and access the API directly.

For neutron, both the paste.ini and the direct-wrap method of
deploying the middleware were chosen, since neutron is in a state of
migration to pecan. Note that if someone deploys pecan-neutron behind
other middleware, any responses provided by that middleware will not
be CORS-enabled, as these responses would be returned before the
headers could be annotated. This results in a response not readable
by the user agent.

OpenStack CrossProject Spec:
   http://specs.openstack.org/openstack/openstack-specs/specs/cors-support.html
Oslo_Middleware Docs:
   http://docs.openstack.org/developer/oslo.middleware/cors.html
OpenStack Cloud Admin Guide:
   http://docs.openstack.org/admin-guide-cloud/cross_project_cors.html
DocImpact: Add link to CORS configuration in admin cloud guide.

Change-Id: I02acea6124d28370d92e7c94ca2d1d6c5c8937ac
This commit is contained in:
Michael Krotscheck 2015-10-19 06:52:04 -07:00
parent ad26d26987
commit 7f65b06033
3 changed files with 24 additions and 2 deletions

View File

@ -5,8 +5,8 @@ use = egg:Paste#urlmap
[composite:neutronapi_v2_0]
use = call:neutron.auth:pipeline_factory
noauth = request_id catch_errors extensions neutronapiapp_v2_0
keystone = request_id catch_errors authtoken keystonecontext extensions neutronapiapp_v2_0
noauth = cors request_id catch_errors extensions neutronapiapp_v2_0
keystone = cors request_id catch_errors authtoken keystonecontext extensions neutronapiapp_v2_0
[filter:request_id]
paste.filter_factory = oslo_middleware:RequestId.factory
@ -14,6 +14,13 @@ paste.filter_factory = oslo_middleware:RequestId.factory
[filter:catch_errors]
paste.filter_factory = oslo_middleware:CatchErrors.factory
[filter:cors]
paste.filter_factory = oslo_middleware.cors:filter_factory
oslo_config_project = neutron
latent_allow_headers = X-Auth-Token, X-Openstack-Request-Id
latent_expose_headers = X-Auth-Token, X-Openstack-Request-Id
latent_allow_methods = GET, PUT, POST, DELETE, PATCH
[filter:keystonecontext]
paste.filter_factory = neutron.auth:NeutronKeystoneContext.factory

View File

@ -13,6 +13,7 @@ namespace = oslo.db
namespace = oslo.policy
namespace = oslo.concurrency
namespace = oslo.messaging
namespace = oslo.middleware.cors
namespace = oslo.service.sslutils
namespace = oslo.service.wsgi
namespace = keystonemiddleware.auth_token

View File

@ -15,6 +15,7 @@
from keystonemiddleware import auth_token
from oslo_config import cfg
from oslo_middleware import cors
from oslo_middleware import request_id
import pecan
@ -74,4 +75,17 @@ def _wrap_app(app):
else:
raise n_exc.InvalidConfigurationOption(
opt_name='auth_strategy', opt_value=cfg.CONF.auth_strategy)
# This should be the last middleware in the list (which results in
# it being the first in the middleware chain). This is to ensure
# that any errors thrown by other middleware, such as an auth
# middleware - are annotated with CORS headers, and thus accessible
# by the browser.
app = cors.CORS(app, cfg.CONF)
app.set_latent(
allow_headers=['X-Auth-Token', 'X-Openstack-Request-Id'],
allow_methods=['GET', 'PUT', 'POST', 'DELETE', 'PATCH'],
expose_headers=['X-Auth-Token', 'X-Openstack-Request-Id']
)
return app