populate request context with X.509 tokenless cred information
Fixes X.509 tokenless auth by properly populating the request context with the necessary credential information. Since Stein release, RBAC has been using the credential information from the Keystone request context instead of the authentication context. Therefore, we'll need to populate the request context with the necessary credential information from the X.509 tokenless authentication context. Closes-Bug: 1811605 Change-Id: I170a91e9ac36990d1e7ec4165dd0337b8f06a938
This commit is contained in:
parent
374b03b015
commit
1b261e8bec
@ -435,7 +435,29 @@ class AuthContextMiddleware(provider_api.ProviderAPIMixin,
|
||||
|
||||
elif self._validate_trusted_issuer(request):
|
||||
auth_context = self._build_tokenless_auth_context(request)
|
||||
|
||||
# NOTE(gyee): we are no longer using auth_context when formulating
|
||||
# the credentials for RBAC. Instead, we are using the (Oslo)
|
||||
# request context. So we'll need to set all the necessary
|
||||
# credential attributes in the request context here.
|
||||
token_attributes = frozenset((
|
||||
'user_id', 'project_id',
|
||||
'domain_id', 'user_domain_id',
|
||||
'project_domain_id', 'user_domain_name',
|
||||
'project_domain_name', 'roles', 'is_admin',
|
||||
'project_name', 'domain_name', 'system_scope',
|
||||
'is_admin_project', 'service_user_id',
|
||||
'service_user_name', 'service_project_id',
|
||||
'service_project_name', 'service_user_domain_id'
|
||||
'service_user_domain_name', 'service_project_domain_id',
|
||||
'service_project_domain_name', 'service_roles'))
|
||||
for attr in token_attributes:
|
||||
if attr in auth_context:
|
||||
setattr(request_context, attr, auth_context[attr])
|
||||
# NOTE(gyee): request_context.token_reference is always
|
||||
# expecting a 'token' key regardless. But in the case of X.509
|
||||
# tokenless auth, we don't need a token. So setting it to None
|
||||
# should be suffice.
|
||||
request_context.token_reference = {'token': None}
|
||||
else:
|
||||
# There is either no auth token in the request or the certificate
|
||||
# issuer is not trusted. No auth context will be set. This
|
||||
|
@ -21,6 +21,7 @@ from six.moves import http_client
|
||||
import webtest
|
||||
|
||||
from keystone.common import authorization
|
||||
from keystone.common import context as keystone_context
|
||||
from keystone.common import provider_api
|
||||
from keystone.common import tokenless_auth
|
||||
import keystone.conf
|
||||
@ -223,6 +224,14 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
else:
|
||||
self.assertEqual(self.user['id'], context['user_id'])
|
||||
|
||||
def _assert_tokenless_request_context(self, request_context,
|
||||
ephemeral_user=False):
|
||||
self.assertIsNotNone(request_context)
|
||||
self.assertEqual(self.project_id, request_context.project_id)
|
||||
self.assertIn(self.role_name, request_context.roles)
|
||||
if not ephemeral_user:
|
||||
self.assertEqual(self.user['id'], request_context.user_id)
|
||||
|
||||
def test_context_already_exists(self):
|
||||
stub_value = uuid.uuid4().hex
|
||||
env = {authorization.AUTH_CONTEXT_ENV: stub_value}
|
||||
@ -317,6 +326,8 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context)
|
||||
|
||||
def test_proj_scope_with_proj_id_only_success(self):
|
||||
env = {}
|
||||
@ -331,6 +342,8 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context)
|
||||
|
||||
def test_proj_scope_with_proj_name_and_proj_dom_id_success(self):
|
||||
env = {}
|
||||
@ -346,6 +359,8 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context)
|
||||
|
||||
def test_proj_scope_with_proj_name_and_proj_dom_name_success(self):
|
||||
env = {}
|
||||
@ -361,6 +376,8 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context)
|
||||
|
||||
def test_proj_scope_with_proj_name_only_fail(self):
|
||||
env = {}
|
||||
@ -390,6 +407,8 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context)
|
||||
|
||||
def test_mapping_with_userid_and_domainname_success(self):
|
||||
env = {}
|
||||
@ -405,6 +424,8 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context)
|
||||
|
||||
def test_mapping_with_username_and_domainid_success(self):
|
||||
env = {}
|
||||
@ -420,6 +441,8 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context)
|
||||
|
||||
def test_only_domain_name_fail(self):
|
||||
env = {}
|
||||
@ -474,6 +497,8 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context)
|
||||
|
||||
def test_domain_disable_fail(self):
|
||||
env = {}
|
||||
@ -543,6 +568,9 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context, ephemeral_user=True)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context,
|
||||
ephemeral_user=True)
|
||||
|
||||
def test_ephemeral_with_default_user_type_success(self):
|
||||
env = {}
|
||||
@ -564,6 +592,9 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context, ephemeral_user=True)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context,
|
||||
ephemeral_user=True)
|
||||
|
||||
def test_ephemeral_any_user_success(self):
|
||||
"""Verify ephemeral user does not need a specified user.
|
||||
@ -585,6 +616,9 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests,
|
||||
req = self._do_middleware_request(extra_environ=env)
|
||||
context = req.environ.get(authorization.AUTH_CONTEXT_ENV)
|
||||
self._assert_tokenless_auth_context(context, ephemeral_user=True)
|
||||
request_context = req.environ.get(keystone_context.REQUEST_CONTEXT_ENV)
|
||||
self._assert_tokenless_request_context(request_context,
|
||||
ephemeral_user=True)
|
||||
|
||||
def test_ephemeral_invalid_scope_fail(self):
|
||||
env = {}
|
||||
|
10
releasenotes/notes/bug-1811605-9d23080d7e949c25.yaml
Normal file
10
releasenotes/notes/bug-1811605-9d23080d7e949c25.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
---
|
||||
fixes:
|
||||
- |
|
||||
[`bug 1811605 <https://bugs.launchpad.net/keystone/+bug/1811605>`_]
|
||||
Fixes X.509 tokenless auth by properly populating the request context
|
||||
with the necessary credential information. Since Stein release, RBAC
|
||||
has been using the credential information from the Keystone request
|
||||
context instead of the authentication context. Therefore, we'll need
|
||||
to populate the request context with the necessary credential
|
||||
information from the X.509 tokenless authentication context.
|
Loading…
x
Reference in New Issue
Block a user