From 7810813d22f1be4e217ad9596ce392b692fadcf5 Mon Sep 17 00:00:00 2001 From: Lance Bragstad Date: Mon, 3 May 2021 20:37:35 +0000 Subject: Only log warnings about token length when length exceeds max_token_size Previously, the fernet token provider would log warnings when a fernet token exceeded 255 characters, which is common for LDAP-backed deployments. The warning is always issued, even when operators configure keystone's max_token_size to a higher value, causing confusion because it appears the configuration value is silently ignored. This commit fixes that issue by using the max_token_size configuration parameter consistently in the fernet token provider. Closes-Bug: 1926483 Change-Id: I4bb54aac9b950d59082a4468203a3249790839d7 (cherry picked from commit 68bfb685d12937dde11d1a335bd992203ec7c293) --- keystone/tests/unit/token/test_fernet_provider.py | 56 ++++++++++++++++++++++ keystone/token/token_formatters.py | 9 ++-- .../notes/bug-1926483-a77ab887e0e7f5c9.yaml | 7 +++ 3 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 releasenotes/notes/bug-1926483-a77ab887e0e7f5c9.yaml diff --git a/keystone/tests/unit/token/test_fernet_provider.py b/keystone/tests/unit/token/test_fernet_provider.py index cc2a49d0b..997b5e6f7 100644 --- a/keystone/tests/unit/token/test_fernet_provider.py +++ b/keystone/tests/unit/token/test_fernet_provider.py @@ -17,6 +17,8 @@ import os from unittest import mock import uuid +import fixtures +from oslo_log import log from oslo_utils import timeutils from keystone import auth @@ -26,6 +28,7 @@ from keystone.common import utils import keystone.conf from keystone import exception from keystone.federation import constants as federation_constants +from keystone.models import token_model from keystone.tests import unit from keystone.tests.unit import default_fixtures from keystone.tests.unit import ksfixtures @@ -51,6 +54,59 @@ class TestFernetTokenProvider(unit.TestCase): self.provider.validate_token, token_id) + def test_log_warning_when_token_exceeds_max_token_size_default(self): + self.logging = self.useFixture(fixtures.FakeLogger(level=log.INFO)) + + token = token_model.TokenModel() + token.user_id = '0123456789abcdef0123456789abcdef0123456789abcdef' + token.project_id = '0123456789abcdef0123456789abcdef0123456789abcdef' + token.expires_at = utils.isotime( + provider.default_expire_time(), subsecond=True) + token.methods = ['password'] + token.audit_id = provider.random_urlsafe_str() + token_id, issued_at = self.provider.generate_id_and_issued_at(token) + expected_output = ( + f'Fernet token created with length of {len(token_id)} characters, ' + 'which exceeds 255 characters' + ) + self.assertIn(expected_output, self.logging.output) + + def test_log_warning_when_token_exceeds_max_token_size_override(self): + self.logging = self.useFixture(fixtures.FakeLogger(level=log.INFO)) + self.config_fixture.config(max_token_size=250) + + token = token_model.TokenModel() + token.user_id = '0123456789abcdef0123456789abcdef0123456789abcdef' + token.project_id = '0123456789abcdef0123456789abcdef0123456789abcdef' + token.expires_at = utils.isotime( + provider.default_expire_time(), subsecond=True) + token.methods = ['password'] + token.audit_id = provider.random_urlsafe_str() + token_id, issued_at = self.provider.generate_id_and_issued_at(token) + expected_output = ( + f'Fernet token created with length of {len(token_id)} characters, ' + 'which exceeds 250 characters' + ) + self.assertIn(expected_output, self.logging.output) + + def test_no_warning_when_token_does_not_exceed_max_token_size(self): + self.config_fixture.config(max_token_size=300) + self.logging = self.useFixture(fixtures.FakeLogger(level=log.INFO)) + + token = token_model.TokenModel() + token.user_id = '0123456789abcdef0123456789abcdef0123456789abcdef' + token.project_id = '0123456789abcdef0123456789abcdef0123456789abcdef' + token.expires_at = utils.isotime( + provider.default_expire_time(), subsecond=True) + token.methods = ['password'] + token.audit_id = provider.random_urlsafe_str() + token_id, issued_at = self.provider.generate_id_and_issued_at(token) + expected_output = ( + f'Fernet token created with length of {len(token_id)} characters, ' + 'which exceeds 255 characters' + ) + self.assertNotIn(expected_output, self.logging.output) + class TestValidate(unit.TestCase): def setUp(self): diff --git a/keystone/token/token_formatters.py b/keystone/token/token_formatters.py index bb407ab09..76220b0ef 100644 --- a/keystone/token/token_formatters.py +++ b/keystone/token/token_formatters.py @@ -156,10 +156,11 @@ class TokenFormatter(object): # characters. Even though Keystone isn't storing a Fernet token # anywhere, we can't say it isn't being stored somewhere else with # those kind of backend constraints. - if len(token) > 255: - LOG.info('Fernet token created with length of %d ' - 'characters, which exceeds 255 characters', - len(token)) + if len(token) > CONF.max_token_size: + LOG.info( + f'Fernet token created with length of {len(token)} ' + f'characters, which exceeds {CONF.max_token_size} characters', + ) return token diff --git a/releasenotes/notes/bug-1926483-a77ab887e0e7f5c9.yaml b/releasenotes/notes/bug-1926483-a77ab887e0e7f5c9.yaml new file mode 100644 index 000000000..040811b79 --- /dev/null +++ b/releasenotes/notes/bug-1926483-a77ab887e0e7f5c9.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + [`bug 1926483 `_] + Keystone will only log warnings about token length for Fernet tokens when + the token length exceeds the value of `keystone.conf [DEFAULT] + max_token_size`. -- cgit v1.2.1