跨域资源共享¶
注意
此功能是 OpenStack Liberty 中的一项新特性。
OpenStack 支持 跨域资源共享 (CORS),这是一种 W3C 规范,定义了一种协议,通过该协议可以放宽用户代理(通常是浏览器)的同源策略。它允许 JavaScript 引擎访问未驻留在相同域、协议或端口上的 API。
此功能对维护一个或多个 OpenStack 定制用户界面的组织最有用,因为它允许这些界面直接访问服务,而无需中间代理服务器。但是,恶意行为者也可能滥用它;请查看下面的安全建议以获取更多信息。
通过配置启用 CORS¶
在大多数情况下,CORS 支持直接内置在服务本身中。要启用它,只需遵循默认配置文件中公开的配置选项,或按照以下模式自行添加即可。
[cors]
allowed_origin = https://first_ui.example.com
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
可以显式添加其他源。要在配置文件中表达这一点,首先从一个 [cors] 分组开始,如上所示,将您的默认配置值放入其中。然后,根据需要添加任意数量的其他配置组,将其命名为 [cors.{something}](每个名称必须唯一)。cors. 后缀的目的是为了便于阅读,我们建议使用合理的、人类可读的字符串
[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
有关 CORS 配置的更多信息,请参阅 跨域资源共享 在 OpenStack 配置参考中。
通过 PasteDeploy 启用 CORS¶
CORS 也可以使用 PasteDeploy 进行配置。首先,确保 OpenStack 的 oslo_middleware 包(版本 2.4.0 或更高版本)在运行服务的 Python 环境中可用。然后,将以下配置块添加到您的 paste.ini 文件中。
[filter:cors]
paste.filter_factory = oslo_middleware.cors:filter_factory
allowed_origin = https://website.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
注意
要在 oslo_middleware v2.4.0 中添加额外的域,请添加另一个过滤器。在 v3.0.0 及更高版本中,您可以在上面的 allowed_origin 字段中添加多个域,用逗号分隔。
安全问题¶
CORS 规范指定一个通配符 *,它允许访问所有用户代理,无论域、协议或主机如何。虽然这种方法有一些有效的用例,但它也允许恶意行为者创建用户界面的令人信服的仿制品,并诱骗用户泄露身份验证凭据。请仔细评估您的用例以及与您的组织相关的任何风险的相关文档。
注意
CORS 规范不支持将此通配符用作 URI 的一部分。将 allowed_origin 设置为 * 会起作用,而 *.openstack.org 则不会。
故障排除¶
CORS 很容易出错,即使一个不正确的属性也会违反规定的协议。以下是一些您可以采取的步骤来解决您的配置问题。
检查服务日志¶
OpenStack 使用的 CORS 中间件提供详细的调试日志,应该可以显示大多数配置问题。以下是一些示例日志消息以及如何解决它们。
问题¶
CORS 请求 来自 源 'http://example.com' 未 被允许。
解决方案¶
从源 http://example.com 收到请求,但是此源未在允许列表中找到。原因可能是多余的端口表示法(端口 80 和 443 不需要指定)。要更正,请确保此主机的配置属性与日志消息中指示的主机完全相同。
问题¶
请求 方法 'DELETE' 未 在 允许的列表中: GET,PUT,POST
解决方案¶
用户代理请求执行 DELETE 请求的权限,但是域的 CORS 配置不允许这样做。要更正,请将此方法添加到 allow_methods 配置属性。
问题¶
请求 标头 'X-Custom-Header' 未 在 允许的列表中: X-Other-Header
解决方案¶
收到带有标头 X-Custom-Header 的请求,该标头不允许。将此标头添加到 allow_headers 配置属性。
打开浏览器的控制台日志¶
大多数浏览器在拒绝 CORS 请求时提供有用的调试输出。通常,当请求成功时,但响应标头不允许浏览器尝试访问的属性时,会发生这种情况。
手动构造 CORS 请求¶
通过使用 curl 或类似工具,您可以触发带有正确构造的 HTTP 请求的 CORS 响应。示例请求和响应可能如下所示。
请求示例
$ curl -I -X OPTIONS https://api.example.com/api -H "Origin: https://ui.example.com"
响应示例
HTTP/1.1 204 No Content
Content-Length: 0
Access-Control-Allow-Origin: https://ui.example.com
Access-Control-Allow-Methods: GET,POST,PUT,DELETE
Access-Control-Expose-Headers: origin,authorization,accept,x-total,x-limit,x-marker,x-client,content-type
Access-Control-Allow-Headers: origin,authorization,accept,x-total,x-limit,x-marker,x-client,content-type
Access-Control-Max-Age: 3600
如果服务未返回任何访问控制标头,请检查服务日志,例如 /var/log/upstart/ironic-api.log,以了解出了什么问题。