Encapsulate auth_token middleware

The existing public routes middleware wrapper subclasses the
keystoneauth middleware. This change refactors it to an encapsulation
of any middleware. In the future this allows for different auth
strategies by passing different auth middleware.

Change-Id: I51ae072e596e987334b79a0b6dfc4905bcf2bcef
Story: 2007656
Task: 39769
This commit is contained in:
Steve Baker 2020-05-08 12:59:47 +12:00
parent c38465eaa8
commit a017447ec3
4 changed files with 15 additions and 15 deletions

View File

@ -16,6 +16,7 @@
# under the License.
import keystonemiddleware.audit as audit_middleware
from keystonemiddleware import auth_token
from oslo_config import cfg
import oslo_middleware.cors as cors_middleware
from oslo_middleware import healthcheck
@ -27,7 +28,7 @@ from ironic.api import config
from ironic.api.controllers import base
from ironic.api import hooks
from ironic.api import middleware
from ironic.api.middleware import auth_token
from ironic.api.middleware import auth_public_routes
from ironic.api.middleware import json_ext
from ironic.common import exception
from ironic.conf import CONF
@ -98,8 +99,10 @@ def setup_app(pecan_config=None, extra_hooks=None):
)
if CONF.auth_strategy == "keystone":
app = auth_token.AuthTokenMiddleware(
app, {"oslo_config_config": cfg.CONF},
app = auth_public_routes.AuthPublicRoutes(
app,
auth=auth_token.AuthProtocol(
app, {"oslo_config_config": cfg.CONF}),
public_api_routes=pecan_config.app.acl_public_routes)
if CONF.profiler.enabled:

View File

@ -12,15 +12,15 @@
# License for the specific language governing permissions and limitations
# under the License.
from ironic.api.middleware import auth_token
from ironic.api.middleware import auth_public_routes
from ironic.api.middleware import json_ext
from ironic.api.middleware import parsable_error
ParsableErrorMiddleware = parsable_error.ParsableErrorMiddleware
AuthTokenMiddleware = auth_token.AuthTokenMiddleware
AuthPublicRoutes = auth_public_routes.AuthPublicRoutes
JsonExtensionMiddleware = json_ext.JsonExtensionMiddleware
__all__ = ('ParsableErrorMiddleware',
'AuthTokenMiddleware',
'AuthPublicRoutes',
'JsonExtensionMiddleware')

View File

@ -14,23 +14,22 @@
import re
from keystonemiddleware import auth_token
from ironic.common import exception
from ironic.common.i18n import _
from ironic.common import utils
class AuthTokenMiddleware(auth_token.AuthProtocol):
"""A wrapper on Keystone auth_token middleware.
class AuthPublicRoutes(object):
"""A wrapper on authentication middleware.
Does not perform verification of authentication tokens
for public routes in the API.
"""
def __init__(self, app, conf, public_api_routes=None):
def __init__(self, app, auth, public_api_routes=None):
api_routes = [] if public_api_routes is None else public_api_routes
self._ironic_app = app
self._middleware = auth
# TODO(mrda): Remove .xml and ensure that doesn't result in a
# 401 Authentication Required instead of 404 Not Found
route_pattern_tpl = '%s(\\.json|\\.xml)?$'
@ -42,8 +41,6 @@ class AuthTokenMiddleware(auth_token.AuthProtocol):
raise exception.ConfigInvalid(
error_msg=_('Cannot compile public API routes: %s') % e)
super(AuthTokenMiddleware, self).__init__(app, conf)
def __call__(self, env, start_response):
path = utils.safe_rstrip(env.get('PATH_INFO'), '/')
@ -56,4 +53,4 @@ class AuthTokenMiddleware(auth_token.AuthProtocol):
if env['is_public_api']:
return self._ironic_app(env, start_response)
return super(AuthTokenMiddleware, self).__call__(env, start_response)
return self._middleware(env, start_response)

View File

@ -36,7 +36,7 @@ default_policies = [
policy.RuleDefault('admin_api',
'role:admin or role:administrator',
description='Legacy rule for cloud admin access'),
# is_public_api is set in the environment from AuthTokenMiddleware
# is_public_api is set in the environment from AuthPublicRoutes
policy.RuleDefault('public_api',
'is_public_api:True',
description='Internal flag for public API routes'),