diff options
author | Adam Young <ayoung@redhat.com> | 2013-07-12 10:23:38 -0400 |
---|---|---|
committer | Jamie Lennox <jamielennox@gmail.com> | 2013-07-17 12:45:52 +1000 |
commit | 88c319e6bce98082f9a90b8b27726793d5366326 (patch) | |
tree | 867ae6600cec6cfd50885eaf86d17dfb27cd1a16 /keystone/auth | |
parent | 3a56c8a68d0f033266f98963261a6d724e506966 (diff) | |
download | keystone-88c319e6bce98082f9a90b8b27726793d5366326.tar.gz keystone-88c319e6bce98082f9a90b8b27726793d5366326.tar.xz keystone-88c319e6bce98082f9a90b8b27726793d5366326.zip |
Pluggable Remote User
Select the code to handle REMOTE_USER based on a config file option
Fixes the REMOTE_USER logic to get the domain name from
REALM, which is the least surprise option.
Disregards the auth_data passed in, as we should be using REMOTE_USER
to get the user name.
External Plugin is now executed in conjunction with the auth methods,
as opposed to in place of them.
DocImpact
blueprint pluggable-remote-user
Change-Id: I9dda6dbe073f03806bdf539db6faa01644109f1c
Diffstat (limited to 'keystone/auth')
-rw-r--r-- | keystone/auth/controllers.py | 22 | ||||
-rw-r--r-- | keystone/auth/plugins/external.py | 80 |
2 files changed, 82 insertions, 20 deletions
diff --git a/keystone/auth/controllers.py b/keystone/auth/controllers.py index 47c44b03..cc4c1605 100644 --- a/keystone/auth/controllers.py +++ b/keystone/auth/controllers.py @@ -321,31 +321,13 @@ class Auth(controller.V3Controller): LOG.exception(e) raise exception.Unauthorized(e) - def _build_remote_user_auth_context(self, context, auth_info, - auth_context): - username = context['REMOTE_USER'] - # FIXME(gyee): REMOTE_USER is not good enough since we are - # requiring domain_id to do user lookup now. Try to get - # the user_id from auth_info for now, assuming external auth - # has check to make sure user is the same as the one specify - # in "identity". - if 'password' in auth_info.get_method_names(): - user_info = auth_info.get_method_data('password') - user_ref = auth_info.lookup_user(user_info['user']) - auth_context['user_id'] = user_ref['id'] - else: - msg = _('Unable to lookup user %s') % (username) - raise exception.Unauthorized(msg) - def authenticate(self, context, auth_info, auth_context): """Authenticate user.""" # user have been authenticated externally if 'REMOTE_USER' in context: - self._build_remote_user_auth_context(context, - auth_info, - auth_context) - return + external = get_auth_method('external') + external.authenticate(context, auth_info, auth_context) # need to aggregate the results in case two or more methods # are specified diff --git a/keystone/auth/plugins/external.py b/keystone/auth/plugins/external.py new file mode 100644 index 00000000..3460ab92 --- /dev/null +++ b/keystone/auth/plugins/external.py @@ -0,0 +1,80 @@ +# vim: tabstop=4 shiftwidth=4 softtabstop=4 + +# Copyright 2013 OpenStack LLC +# +# 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. + +"""Keystone External Authentication Plugin""" + +from keystone.common import config +from keystone import exception + + +CONF = config.CONF + + +class ExternalDefault(object): + def authenticate(self, context, auth_info, auth_context): + """Use REMOTE_USER to look up the user in the identity backend + + auth_context is an in-out variable that will be updated with the + username from the REMOTE_USER environment variable. + """ + try: + REMOTE_USER = context['REMOTE_USER'] + except KeyError: + msg = _('No authenticated user') + raise exception.Unauthorized(msg) + try: + names = REMOTE_USER.split('@') + username = names.pop(0) + domain_id = CONF.identity.default_domain_id + user_ref = auth_info.identity_api.get_user_by_name(username, + domain_id) + auth_context['user_id'] = user_ref['id'] + except Exception: + msg = _('Unable to lookup user %s') % (REMOTE_USER) + raise exception.Unauthorized(msg) + + +class ExternalDomain(object): + def authenticate(self, context, auth_info, auth_context): + """Use REMOTE_USER to look up the user in the identity backend + + auth_context is an in-out variable that will be updated with the + username from the REMOTE_USER environment variable. + + If REMOTE_USER contains an `@` assume that the substring before the @ + is the username, and the substring after the @ is the domain name. + """ + try: + REMOTE_USER = context['REMOTE_USER'] + except KeyError: + msg = _('No authenticated user') + raise exception.Unauthorized(msg) + try: + names = REMOTE_USER.split('@') + username = names.pop(0) + if names: + domain_name = names[0] + domain_ref = (auth_info.identity_api. + get_domain_by_name(domain_name)) + domain_id = domain_ref['id'] + else: + domain_id = CONF.identity.default_domain_id + user_ref = auth_info.identity_api.get_user_by_name(username, + domain_id) + auth_context['user_id'] = user_ref['id'] + except Exception: + msg = _('Unable to lookup user %s') % (REMOTE_USER) + raise exception.Unauthorized(msg) |