placement: skip authentication on root URI

The placement API GET / is for version discovery. Skip authentication
on this URL.

The change to test_deploy is required to make it request a URL that
requires authentication. It had been using /.

Change-Id: I5ed1f7a607620c43671e90eaf8a1f6285f1d15e4
Closes-Bug: #1733630
This commit is contained in:
Hongbin Lu 2017-11-21 20:05:21 +00:00 committed by Chris Dent
parent 81544829d1
commit c4c1770475
4 changed files with 48 additions and 7 deletions

View File

@ -11,6 +11,7 @@
# under the License.
from keystonemiddleware import auth_token
from oslo_context import context
from oslo_db.sqlalchemy import enginefacade
from oslo_log import log as logging
@ -37,6 +38,9 @@ class NoAuthMiddleware(Middleware):
@webob.dec.wsgify
def __call__(self, req):
if req.environ['PATH_INFO'] == '/':
return self.application
if 'X-Auth-Token' not in req.headers:
return webob.exc.HTTPUnauthorized()
@ -68,9 +72,37 @@ class PlacementKeystoneContext(Middleware):
ctx = RequestContext.from_environ(
req.environ, request_id=req_id)
if ctx.user_id is None:
if ctx.user_id is None and req.environ['PATH_INFO'] != '/':
LOG.debug("Neither X_USER_ID nor X_USER found in request")
return webob.exc.HTTPUnauthorized()
req.environ['placement.context'] = ctx
return self.application
class PlacementAuthProtocol(auth_token.AuthProtocol):
"""A wrapper on Keystone auth_token middleware.
Does not perform verification of authentication tokens
for root in the API.
"""
def __init__(self, app, conf):
self._placement_app = app
super(PlacementAuthProtocol, self).__init__(app, conf)
def __call__(self, environ, start_response):
if environ['PATH_INFO'] == '/':
return self._placement_app(environ, start_response)
return super(PlacementAuthProtocol, self).__call__(
environ, start_response)
def filter_factory(global_conf, **local_conf):
conf = global_conf.copy()
conf.update(local_conf)
def auth_filter(app):
return PlacementAuthProtocol(app, conf)
return auth_filter

View File

@ -11,7 +11,6 @@
# under the License.
"""Deployment handling for Placmenent API."""
from keystonemiddleware import auth_token
import oslo_middleware
from oslo_middleware import cors
@ -41,7 +40,7 @@ def deploy(conf, project_name):
# Do not use 'oslo_config_project' param here as the conf
# location may have been overridden earlier in the deployment
# process with OS_PLACEMENT_CONFIG_DIR in wsgi.py.
auth_middleware = auth_token.filter_factory(
auth_middleware = auth.filter_factory(
{}, oslo_config_config=conf)
# Pass in our CORS config, if any, manually as that's a)

View File

@ -11,12 +11,22 @@ defaults:
accept: application/json
tests:
- name: no token gets 401
- name: no token gets 200 at root
GET: /
status: 401
status: 200
- name: with token 200
- name: with token 200 at root
GET: /
request_headers:
x-auth-token: admin:admin
status: 200
- name: no token gets 401
GET: /resource_providers
status: 401
- name: with token 200
GET: /resource_providers
request_headers:
x-auth-token: admin:admin
status: 200

View File

@ -35,7 +35,7 @@ class DeployTest(test.NoDBTestCase):
# ensure that the auth_token middleware is chosen
self.flags(auth_strategy='keystone', group='api')
app = deploy.deploy(CONF, 'nova')
req = webob.Request.blank('/', method="GET")
req = webob.Request.blank('/resource_providers', method="GET")
response = req.get_response(app)