add authtoken-middleware

Add authtoken middleware for integrating with the OpenStack Identity API
and handling authorization enforcement based upon the data within the
OpenStack Identity tokens

Change-Id: I8056d69657d0a98b4446a494877f7b965ceb786f
This commit is contained in:
zhuli 2017-08-25 10:22:59 +08:00
parent 57e4c042ca
commit ee48522720
5 changed files with 114 additions and 1 deletions

View File

@ -15,6 +15,8 @@
import pecan
from oslo_config import cfg
from cyborg.api import config
from cyborg.api import hooks
from cyborg.api import middleware
@ -48,6 +50,10 @@ def setup_app(pecan_config=None, extra_hooks=None):
wrap_app=middleware.ParsableErrorMiddleware
)
app = middleware.AuthTokenMiddleware(
app, dict(cfg.CONF),
public_api_routes=pecan_config.app.acl_public_routes)
return app

View File

@ -13,9 +13,12 @@
# License for the specific language governing permissions and limitations
# under the License.
from cyborg.api.middleware import auth_token
from cyborg.api.middleware import parsable_error
ParsableErrorMiddleware = parsable_error.ParsableErrorMiddleware
AuthTokenMiddleware = auth_token.AuthTokenMiddleware
__all__ = ('ParsableErrorMiddleware',)
__all__ = ('ParsableErrorMiddleware',
'AuthTokenMiddleware')

View File

@ -0,0 +1,64 @@
# Copyright 2017 Huawei Technologies Co.,LTD.
# All Rights Reserved.
#
# 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 re
from keystonemiddleware import auth_token
from oslo_log import log
from cyborg.common import exception
from cyborg.common.i18n import _
from cyborg.common import utils
LOG = log.getLogger(__name__)
class AuthTokenMiddleware(auth_token.AuthProtocol):
"""A wrapper on Keystone auth_token middleware.
Does not perform verification of authentication tokens
for public routes in the API.
"""
def __init__(self, app, conf, public_api_routes=None):
public_api_routes = public_api_routes or []
self.app = app
route_pattern_tpl = '%s(\.json)?$'
try:
self.public_api_routes = [re.compile(route_pattern_tpl % route_tpl)
for route_tpl in public_api_routes]
except re.error as e:
msg = _('Cannot compile public API routes: %s') % e
LOG.error(msg)
raise exception.ConfigInvalid(error_msg=msg)
super(AuthTokenMiddleware, self).__init__(app, conf)
def __call__(self, env, start_response):
path = utils.safe_rstrip(env.get('PATH_INFO'), '/')
# The information whether the API call is being performed against the
# public API is required for some other components. Saving it to the
# WSGI environment is reasonable thereby.
env['is_public_api'] = any(map(lambda pattern: re.match(pattern, path),
self.public_api_routes))
if env['is_public_api']:
return self.app(env, start_response)
return super(AuthTokenMiddleware, self).__call__(env, start_response)

39
cyborg/common/utils.py Normal file
View File

@ -0,0 +1,39 @@
# Copyright 2017 Huawei Technologies Co.,LTD.
# All Rights Reserved.
#
# 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.
"""Utilities and helper functions."""
from oslo_log import log
import six
LOG = log.getLogger(__name__)
def safe_rstrip(value, chars=None):
"""Removes trailing characters from a string if that does not make it empty
:param value: A string value that will be stripped.
:param chars: Characters to remove.
:return: Stripped value.
"""
if not isinstance(value, six.string_types):
LOG.warning("Failed to remove trailing character. Returning "
"original object. Supplied object is not a string: "
"%s,", value)
return value
return value.rstrip(chars) or value

View File

@ -21,3 +21,4 @@ oslo.versionedobjects>=1.17.0 # Apache-2.0
SQLAlchemy!=1.1.5,!=1.1.6,!=1.1.7,!=1.1.8,>=1.0.10 # MIT
alembic>=0.8.10 # MIT
stevedore>=1.20.0 # Apache-2.0
keystonemiddleware>=4.17.0 # Apache-2.0