feat: allow for forcing asymmetric jwts (#32045)
Add a temporary feature toggle to force the LMS to only produce asymmetric JWTs. This is a part of DEPR of Symmetric JWTs: https://github.com/openedx/public-engineering/issues/83
This commit is contained in:
@@ -6,8 +6,9 @@ import logging
|
||||
from time import time
|
||||
|
||||
from django.conf import settings
|
||||
from edx_django_utils.monitoring import set_custom_attribute
|
||||
from edx_django_utils.monitoring import increment, set_custom_attribute
|
||||
from edx_rbac.utils import create_role_auth_claim_for_user
|
||||
from edx_toggles.toggles import SettingToggle
|
||||
from jwkest import jwk
|
||||
from jwkest.jws import JWS
|
||||
|
||||
@@ -159,6 +160,12 @@ def _create_jwt(
|
||||
secret (string): Overrides configured JWT secret (signing) key.
|
||||
"""
|
||||
use_asymmetric_key = _get_use_asymmetric_key_value(is_restricted, use_asymmetric_key)
|
||||
# Enable monitoring of key type used. Use increment in case there are multiple calls in a transaction.
|
||||
if use_asymmetric_key:
|
||||
increment('create_asymmetric_jwt_count')
|
||||
else:
|
||||
increment('create_symmetric_jwt_count')
|
||||
|
||||
# Default scopes should only contain non-privileged data.
|
||||
# Do not be misled by the fact that `email` and `profile` are default scopes. They
|
||||
# were included for legacy compatibility, even though they contain privileged data.
|
||||
@@ -188,10 +195,27 @@ def _create_jwt(
|
||||
return _encode_and_sign(payload, use_asymmetric_key, secret)
|
||||
|
||||
|
||||
# .. toggle_name: JWT_AUTH_FORCE_CREATE_ASYMMETRIC
|
||||
# .. toggle_implementation: SettingToggle
|
||||
# .. toggle_default: False
|
||||
# .. toggle_description: When True, forces the LMS to only create JWTs signed with the asymmetric
|
||||
# key. This is a temporary rollout toggle for DEPR of symmetric JWTs.
|
||||
# .. toggle_use_cases: temporary
|
||||
# .. toggle_creation_date: 2023-04-10
|
||||
# .. toggle_target_removal_date: 2023-07-31
|
||||
# .. toggle_tickets: https://github.com/openedx/public-engineering/issues/83
|
||||
JWT_AUTH_FORCE_CREATE_ASYMMETRIC = SettingToggle(
|
||||
'JWT_AUTH_FORCE_CREATE_ASYMMETRIC', default=False, module_name=__name__
|
||||
)
|
||||
|
||||
|
||||
def _get_use_asymmetric_key_value(is_restricted, use_asymmetric_key):
|
||||
"""
|
||||
Returns the value to use for use_asymmetric_key.
|
||||
"""
|
||||
if JWT_AUTH_FORCE_CREATE_ASYMMETRIC.is_enabled():
|
||||
return True
|
||||
|
||||
return use_asymmetric_key or is_restricted
|
||||
|
||||
|
||||
|
||||
@@ -73,6 +73,11 @@ class TestCreateJWTs(AccessTokenMixin, TestCase):
|
||||
jwt_token = self._create_jwt_for_token(DOTAdapter(), use_asymmetric_key=True)
|
||||
self._assert_jwt_is_valid(jwt_token, should_be_asymmetric_key=True)
|
||||
|
||||
@override_settings(JWT_AUTH_FORCE_CREATE_ASYMMETRIC=True)
|
||||
def test_dot_create_jwt_for_token_forced_asymmetric(self):
|
||||
jwt_token = self._create_jwt_for_token(DOTAdapter(), use_asymmetric_key=False)
|
||||
self._assert_jwt_is_valid(jwt_token, should_be_asymmetric_key=True)
|
||||
|
||||
def test_create_jwt_for_token_default_expire_seconds(self):
|
||||
oauth_adapter = DOTAdapter()
|
||||
jwt_token = self._create_jwt_for_token(oauth_adapter, use_asymmetric_key=False)
|
||||
|
||||
Reference in New Issue
Block a user