Revert "Support ... x-forwarded-for header"

This reverts commit e3679217d1.

This commit broke using the heat API when client requests were
behind a proxy (this sets the X-Forwarded-For header)
and effectively causes the heat-api to return the clients
IP address back in the request via the location header.

I believe the original (unapproved) heat blueprint for
this feature should have used X-Forwarded-Host instead.

Closes-bug: #1316754

Change-Id: I1b38ececf59545a3c13c7ebf2c33be97f4332ac0
changes/39/92439/2
Dan Prince 9 years ago
parent c86655b517
commit 19686f0910
  1. 14
      etc/heat/api-paste.ini
  2. 9
      etc/heat/heat.conf.sample
  3. 35
      heat/api/middleware/x_forwarded_for.py
  4. 5
      heat/api/openstack/__init__.py
  5. 53
      heat/tests/test_x_forwarded_for_middleware.py

@ -1,7 +1,7 @@
# heat-api pipeline
[pipeline:heat-api]
pipeline = faultwrap ssl xforwardedfor versionnegotiation authurl authtoken context apiv1app
pipeline = faultwrap ssl versionnegotiation authurl authtoken context apiv1app
# heat-api pipeline for standalone heat
# ie. uses alternative auth backend that authenticates users against keystone
@ -12,7 +12,7 @@ pipeline = faultwrap ssl xforwardedfor versionnegotiation authurl authtoken cont
# flavor = standalone
#
[pipeline:heat-api-standalone]
pipeline = faultwrap ssl xforwardedfor versionnegotiation authurl authpassword context apiv1app
pipeline = faultwrap ssl versionnegotiation authurl authpassword context apiv1app
# heat-api pipeline for custom cloud backends
# i.e. in heat.conf:
@ -20,7 +20,7 @@ pipeline = faultwrap ssl xforwardedfor versionnegotiation authurl authpassword c
# flavor = custombackend
#
[pipeline:heat-api-custombackend]
pipeline = faultwrap xforwardedfor versionnegotiation context custombackendauth apiv1app
pipeline = faultwrap versionnegotiation context custombackendauth apiv1app
# heat-api-cfn pipeline
[pipeline:heat-api-cfn]
@ -33,12 +33,12 @@ pipeline = cfnversionnegotiation ec2authtoken context apicfnv1app
# heat-api-cloudwatch pipeline
[pipeline:heat-api-cloudwatch]
pipeline = xforwardedfor versionnegotiation ec2authtoken authtoken context apicwapp
pipeline = versionnegotiation ec2authtoken authtoken context apicwapp
# heat-api-cloudwatch pipeline for standalone heat
# relies exclusively on authenticating with ec2 signed requests
[pipeline:heat-api-cloudwatch-standalone]
pipeline = xforwardedfor versionnegotiation ec2authtoken context apicwapp
pipeline = versionnegotiation ec2authtoken context apicwapp
[app:apiv1app]
paste.app_factory = heat.common.wsgi:app_factory
@ -52,10 +52,6 @@ heat.app_factory = heat.api.cfn.v1:API
paste.app_factory = heat.common.wsgi:app_factory
heat.app_factory = heat.api.cloudwatch:API
[filter:xforwardedfor]
paste.filter_factory = heat.common.wsgi:filter_factory
heat.filter_factory = heat.api.openstack:x_forwarded_for_middleware_filter
[filter:versionnegotiation]
paste.filter_factory = heat.common.wsgi:filter_factory
heat.filter_factory = heat.api.openstack:version_negotiation_filter

@ -10,15 +10,6 @@
#secure_proxy_ssl_header=X-Forwarded-Proto
#
# Options defined in heat.api.middleware.x_forwarded_for
#
# The HTTP header that will be used as remote address. (string
# value)
#forward_header_name=X-Forwarded-For
#
# Options defined in heat.common.config
#

@ -1,35 +0,0 @@
# -*- encoding: utf-8 -*-
#
# Licensed 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.
from oslo.config import cfg
from heat.common import wsgi
x_forwarded_middleware_opts = [
cfg.StrOpt('forward_header_name',
default='X-Forwarded-For',
help="The HTTP header that will be used as remote address.")
]
cfg.CONF.register_opts(x_forwarded_middleware_opts)
class XForwardedForMiddleware(wsgi.Middleware):
"""A middleware that replaces the request hostname with proxy hostname.
"""
def __init__(self, application):
super(XForwardedForMiddleware, self).__init__(application)
def process_request(self, req):
# If 'forward_header_name' header was not found, then do not
# change the host name
req.host = req.headers.get(cfg.CONF.forward_header_name, req.host)

@ -14,7 +14,6 @@
from heat.api.middleware.fault import FaultWrapper
from heat.api.middleware.ssl import SSLMiddleware
from heat.api.middleware.version_negotiation import VersionNegotiationFilter
from heat.api.middleware.x_forwarded_for import XForwardedForMiddleware
from heat.api.openstack import versions
@ -29,7 +28,3 @@ def faultwrap_filter(app, conf, **local_conf):
def sslmiddleware_filter(app, conf, **local_conf):
return SSLMiddleware(app)
def x_forwarded_for_middleware_filter(app, conf, **local_conf):
return XForwardedForMiddleware(app)

@ -1,53 +0,0 @@
# -*- encoding: utf-8 -*-
#
# Licensed 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.
import webob
from heat.api.middleware import x_forwarded_for
from oslo.config import cfg
from heat.tests.common import HeatTestCase
class XForwardedForMiddlewareTest(HeatTestCase):
def test_default_header_found(self):
headers = {'X-Forwarded-For': 'www.test.com'}
middleware = x_forwarded_for.XForwardedForMiddleware(None)
request = webob.Request.blank('/stacks', headers=headers)
self.assertIsNone(middleware.process_request(request))
self.assertEqual('www.test.com', request.host)
def test_custom_header_found(self):
cfg.CONF.set_override('forward_header_name', 'X-Fwd-Custom')
headers = {'X-Fwd-Custom': 'www.test.com'}
middleware = x_forwarded_for.XForwardedForMiddleware(None)
request = webob.Request.blank('/stacks', headers=headers)
self.assertIsNone(middleware.process_request(request))
self.assertEqual('www.test.com', request.host)
def test_default_header_not_found(self):
headers = {}
middleware = x_forwarded_for.XForwardedForMiddleware(None)
request = webob.Request.blank('/stacks', headers=headers)
self.assertIsNone(middleware.process_request(request))
self.assertEqual('localhost:80', request.host)
def test_custom_header_not_found(self):
cfg.CONF.set_override('forward_header_name', 'X-Fwd-Custom')
headers = {}
middleware = x_forwarded_for.XForwardedForMiddleware(None)
request = webob.Request.blank('/stacks', headers=headers)
self.assertIsNone(middleware.process_request(request))
self.assertEqual('localhost:80', request.host)
Loading…
Cancel
Save