Merge "Only validate tokens once per request"
This commit is contained in:
commit
a0e9efae72
keystone
releasenotes/notes
@ -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)
|
||||
|
||||
|
@ -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()
|
||||
|
9
releasenotes/notes/bug-1819036-e2d24655c70d0aad.yaml
Normal file
9
releasenotes/notes/bug-1819036-e2d24655c70d0aad.yaml
Normal file
@ -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.
|
Loading…
x
Reference in New Issue
Block a user