diff --git a/keystonemiddleware/auth_token/__init__.py b/keystonemiddleware/auth_token/__init__.py index 75a6ec5e..89fed656 100644 --- a/keystonemiddleware/auth_token/__init__.py +++ b/keystonemiddleware/auth_token/__init__.py @@ -491,7 +491,8 @@ class BaseAuthProtocol(object): try: data, user_auth_ref = self._do_fetch_token(request.user_token) self._validate_token(user_auth_ref) - self._confirm_token_bind(user_auth_ref, request) + if not request.service_token: + self._confirm_token_bind(user_auth_ref, request) except ksm_exceptions.InvalidToken: self.log.info(_LI('Invalid user token')) request.user_token_valid = False diff --git a/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py b/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py index ae34a6e1..942f2c03 100644 --- a/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py +++ b/keystonemiddleware/tests/unit/auth_token/test_auth_token_middleware.py @@ -2049,6 +2049,35 @@ class CommonCompositeAuthTests(object): expected_status=403) self.assertEqual(FakeApp.FORBIDDEN, resp.body) + def assert_kerberos_composite_bind(self, user_token, service_token, + bind_level): + conf = { + 'enforce_token_bind': bind_level, + 'auth_version': self.auth_version, + } + self.set_middleware(conf=conf) + + req = webob.Request.blank('/') + req.headers['X-Auth-Token'] = user_token + req.headers['X-Service-Token'] = service_token + + req.environ['REMOTE_USER'] = self.examples.SERVICE_KERBEROS_BIND + req.environ['AUTH_TYPE'] = 'Negotiate' + + resp = req.get_response(self.middleware) + + self.assertEqual(200, resp.status_int) + self.assertEqual(FakeApp.SUCCESS, resp.body) + self.assertIn('keystone.token_info', req.environ) + + def test_composite_auth_with_bind(self): + token = self.token_dict['uuid_token_bind'] + service_token = self.token_dict['uuid_service_token_bind'] + + self.assert_kerberos_composite_bind(token, + service_token, + bind_level='required') + class v2CompositeAuthTests(BaseAuthTokenMiddlewareTest, CommonCompositeAuthTests, @@ -2069,9 +2098,13 @@ class v2CompositeAuthTests(BaseAuthTokenMiddlewareTest, uuid_token_default = self.examples.UUID_TOKEN_DEFAULT uuid_service_token_default = self.examples.UUID_SERVICE_TOKEN_DEFAULT + uuid_token_bind = self.examples.UUID_TOKEN_BIND + uuid_service_token_bind = self.examples.UUID_SERVICE_TOKEN_BIND self.token_dict = { 'uuid_token_default': uuid_token_default, 'uuid_service_token_default': uuid_service_token_default, + 'uuid_token_bind': uuid_token_bind, + 'uuid_service_token_bind': uuid_service_token_bind, } self.requests_mock.get(BASE_URI, @@ -2086,7 +2119,9 @@ class v2CompositeAuthTests(BaseAuthTokenMiddlewareTest, status_code=200) for token in (self.examples.UUID_TOKEN_DEFAULT, - self.examples.UUID_SERVICE_TOKEN_DEFAULT,): + self.examples.UUID_SERVICE_TOKEN_DEFAULT, + self.examples.UUID_TOKEN_BIND, + self.examples.UUID_SERVICE_TOKEN_BIND): text = self.examples.JSON_TOKEN_RESPONSES[token] self.requests_mock.get('%s/v2.0/tokens/%s' % (BASE_URI, token), text=text) @@ -2120,9 +2155,13 @@ class v3CompositeAuthTests(BaseAuthTokenMiddlewareTest, uuid_token_default = self.examples.v3_UUID_TOKEN_DEFAULT uuid_serv_token_default = self.examples.v3_UUID_SERVICE_TOKEN_DEFAULT + uuid_token_bind = self.examples.v3_UUID_TOKEN_BIND + uuid_service_token_bind = self.examples.v3_UUID_SERVICE_TOKEN_BIND self.token_dict = { 'uuid_token_default': uuid_token_default, 'uuid_service_token_default': uuid_serv_token_default, + 'uuid_token_bind': uuid_token_bind, + 'uuid_service_token_bind': uuid_service_token_bind, } self.requests_mock.get(BASE_URI, json=VERSION_LIST_v3, status_code=300) diff --git a/keystonemiddleware/tests/unit/client_fixtures.py b/keystonemiddleware/tests/unit/client_fixtures.py index ea36a018..f150b4e6 100644 --- a/keystonemiddleware/tests/unit/client_fixtures.py +++ b/keystonemiddleware/tests/unit/client_fixtures.py @@ -105,6 +105,7 @@ class Examples(fixtures.Fixture): self.SIGNING_CERT = f.read() self.KERBEROS_BIND = 'USER@REALM' + self.SERVICE_KERBEROS_BIND = 'SERVICE_USER@SERVICE_REALM' self.SIGNING_KEY_FILE = os.path.join(KEYDIR, 'signing_key.pem') with open(self.SIGNING_KEY_FILE) as f: @@ -127,7 +128,9 @@ class Examples(fixtures.Fixture): self.v3_UUID_TOKEN_UNKNOWN_BIND = '7ed9781b62cd4880b8d8c6788ab1d1e2' self.UUID_SERVICE_TOKEN_DEFAULT = 'fe4c0710ec2f492748596c1b53ab124' + self.UUID_SERVICE_TOKEN_BIND = '5e43439613d34a13a7e03b2762bd08ab' self.v3_UUID_SERVICE_TOKEN_DEFAULT = 'g431071bbc2f492748596c1b53cb229' + self.v3_UUID_SERVICE_TOKEN_BIND = 'be705e4426d0449a89e35ae21c380a05' revoked_token = self.REVOKED_TOKEN if isinstance(revoked_token, six.text_type): @@ -321,6 +324,17 @@ class Examples(fixtures.Fixture): token['access']['token']['bind'] = {'kerberos': self.KERBEROS_BIND} self.TOKEN_RESPONSES[self.UUID_TOKEN_BIND] = token + token = fixture.V2Token(token_id=self.UUID_SERVICE_TOKEN_BIND, + tenant_id=SERVICE_PROJECT_ID, + tenant_name=SERVICE_PROJECT_NAME, + user_id=SERVICE_USER_ID, + user_name=SERVICE_USER_NAME) + token.add_role(SERVICE_ROLE_NAME1) + token.add_role(SERVICE_ROLE_NAME2) + token['access']['token']['bind'] = { + 'kerberos': self.SERVICE_KERBEROS_BIND} + self.TOKEN_RESPONSES[self.UUID_SERVICE_TOKEN_BIND] = token + token = fixture.V2Token(token_id=self.UUID_TOKEN_UNKNOWN_BIND, tenant_id=PROJECT_ID, tenant_name=PROJECT_NAME, @@ -405,6 +419,21 @@ class Examples(fixtures.Fixture): token['token']['bind'] = {'kerberos': self.KERBEROS_BIND} self.TOKEN_RESPONSES[self.v3_UUID_TOKEN_BIND] = token + token = fixture.V3Token(user_id=SERVICE_USER_ID, + user_name=SERVICE_USER_NAME, + user_domain_id=SERVICE_DOMAIN_ID, + user_domain_name=SERVICE_DOMAIN_NAME, + project_id=SERVICE_PROJECT_ID, + project_name=SERVICE_PROJECT_NAME, + project_domain_id=SERVICE_DOMAIN_ID, + project_domain_name=SERVICE_DOMAIN_NAME) + token.add_role(name=SERVICE_ROLE_NAME1) + token.add_role(name=SERVICE_ROLE_NAME2) + svc = token.add_service(self.SERVICE_TYPE) + svc.add_endpoint('public', self.SERVICE_URL) + token['token']['bind'] = {'kerberos': self.SERVICE_KERBEROS_BIND} + self.TOKEN_RESPONSES[self.v3_UUID_SERVICE_TOKEN_BIND] = token + token = fixture.V3Token(user_id=USER_ID, user_name=USER_NAME, user_domain_id=DOMAIN_ID,