diff options
author | Zuul <zuul@review.openstack.org> | 2019-04-01 16:10:35 +0000 |
---|---|---|
committer | Gerrit Code Review <review@openstack.org> | 2019-04-01 16:10:35 +0000 |
commit | e2a3ffbfa60be2b39aeeaecfc4869f45b5d92b7e (patch) | |
tree | 74e71115dbb95ef0182b2cd15e93f11c995729a0 | |
parent | c45444494a69de1a5b9467f40d7aa5506d9c891e (diff) | |
parent | 86cf26310a9a049ab6bbd59f3e8a29ba1fe86b17 (diff) | |
download | keystone-e2a3ffbfa60be2b39aeeaecfc4869f45b5d92b7e.tar.gz |
Merge "Only validate tokens once per request" into stable/stein
-rw-r--r-- | keystone/server/flask/request_processing/middleware/auth_context.py | 16 | ||||
-rw-r--r-- | keystone/tests/unit/test_middleware.py | 23 | ||||
-rw-r--r-- | releasenotes/notes/bug-1819036-e2d24655c70d0aad.yaml | 9 |
3 files changed, 41 insertions, 7 deletions
diff --git a/keystone/server/flask/request_processing/middleware/auth_context.py b/keystone/server/flask/request_processing/middleware/auth_context.py index 7961416d3..56f1df397 100644 --- a/keystone/server/flask/request_processing/middleware/auth_context.py +++ b/keystone/server/flask/request_processing/middleware/auth_context.py @@ -237,11 +237,12 @@ class AuthContextMiddleware(provider_api.ProviderAPIMixin, def __init__(self, app): super(AuthContextMiddleware, self).__init__(app, log=LOG) + self.token = None def fetch_token(self, token, **kwargs): try: - token_model = self.token_provider_api.validate_token(token) - return render_token.render_token_response_from_model(token_model) + self.token = self.token_provider_api.validate_token(token) + return render_token.render_token_response_from_model(self.token) except exception.TokenNotFound: raise auth_token.InvalidToken(_('Could not find token')) @@ -416,10 +417,11 @@ class AuthContextMiddleware(provider_api.ProviderAPIMixin, elif request.token_auth.has_user_token: # Keystone enforces policy on some values that other services # do not, and should not, use. This adds them in to the context. - token = PROVIDERS.token_provider_api.validate_token( - request.user_token - ) - self._keystone_specific_values(token, request_context) + if not self.token: + self.token = PROVIDERS.token_provider_api.validate_token( + request.user_token + ) + self._keystone_specific_values(self.token, request_context) request_context.auth_token = request.user_token auth_context = request_context.to_policy_values() additional = { @@ -429,7 +431,7 @@ class AuthContextMiddleware(provider_api.ProviderAPIMixin, 'domain_id': request_context._domain_id, 'domain_name': request_context.domain_name, 'group_ids': request_context.group_ids, - 'token': token + 'token': self.token } auth_context.update(additional) diff --git a/keystone/tests/unit/test_middleware.py b/keystone/tests/unit/test_middleware.py index 8b4aa3645..047d7d5e1 100644 --- a/keystone/tests/unit/test_middleware.py +++ b/keystone/tests/unit/test_middleware.py @@ -17,9 +17,11 @@ import hashlib import uuid import fixtures +import mock from six.moves import http_client import webtest +from keystone.auth import core as auth_core from keystone.common import authorization from keystone.common import context as keystone_context from keystone.common import provider_api @@ -730,3 +732,24 @@ class AuthContextMiddlewareTest(test_backend_sql.SqlTests, headers = {authorization.AUTH_TOKEN_HEADER: 'NOT-ADMIN'} self._do_middleware_request(headers=headers) self.assertIn('Invalid user token', log_fix.output) + + def test_token_is_cached(self): + # Make sure we only call PROVIDERS.token_provider_api.validate_token() + # once while in middleware so that we're mindful of performance + context = auth_core.AuthContext( + user_id=self.user['id'], methods=['password'] + ) + token = PROVIDERS.token_provider_api.issue_token( + context['user_id'], context['methods'], project_id=self.project_id, + auth_context=context + ) + headers = { + authorization.AUTH_TOKEN_HEADER: token.id.encode('utf-8') + } + with mock.patch.object(PROVIDERS.token_provider_api, + 'validate_token', + return_value=token) as token_mock: + self._do_middleware_request( + path='/v3/projects', method='get', headers=headers + ) + token_mock.assert_called_once() diff --git a/releasenotes/notes/bug-1819036-e2d24655c70d0aad.yaml b/releasenotes/notes/bug-1819036-e2d24655c70d0aad.yaml new file mode 100644 index 000000000..adf7fb692 --- /dev/null +++ b/releasenotes/notes/bug-1819036-e2d24655c70d0aad.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + [`bug 1819036 <https://bugs.launchpad.net/keystone/+bug/1819036>`_] + Middleware that processes requests in front of keystone now caches tokens + per request, eliminating unnecessary round trips to validate tokens on + every request. This change doesn't require the usage of any configuration + options to take effect. The fix for this bug improved performance ~20% during + testing and impacts most of keystone's API. |