diff --git a/authentik/providers/oauth2/tests/test_token_cc_user_pw.py b/authentik/providers/oauth2/tests/test_token_cc_user_pw.py index 467e4801493f..c02356ed3d8f 100644 --- a/authentik/providers/oauth2/tests/test_token_cc_user_pw.py +++ b/authentik/providers/oauth2/tests/test_token_cc_user_pw.py @@ -8,7 +8,12 @@ from authentik.blueprints.tests import apply_blueprint from authentik.core.models import Application, Group, Token, TokenIntents, UserTypes -from authentik.core.tests.utils import create_test_admin_user, create_test_cert, create_test_flow +from authentik.core.tests.utils import ( + create_test_admin_user, + create_test_cert, + create_test_flow, + create_test_user, +) from authentik.policies.models import PolicyBinding from authentik.providers.oauth2.constants import ( GRANT_TYPE_CLIENT_CREDENTIALS, @@ -182,6 +187,47 @@ def test_successful(self): self.assertEqual(jwt["given_name"], self.user.name) self.assertEqual(jwt["preferred_username"], self.user.username) + def test_successful_two_tokens(self): + """test successful when two app passwords with the same key exist""" + Token.objects.create( + identifier="sa-token-two", + user=create_test_user(), + intent=TokenIntents.INTENT_APP_PASSWORD, + expiring=False, + key=self.token.key, + ) + + response = self.client.post( + reverse("authentik_providers_oauth2:token"), + { + "grant_type": GRANT_TYPE_CLIENT_CREDENTIALS, + "scope": f"{SCOPE_OPENID} {SCOPE_OPENID_EMAIL} {SCOPE_OPENID_PROFILE}", + "client_id": self.provider.client_id, + "username": "sa", + "password": self.token.key, + }, + ) + self.assertEqual(response.status_code, 200) + body = loads(response.content.decode()) + self.assertEqual(body["token_type"], TOKEN_TYPE) + _, alg = self.provider.jwt_key + jwt = decode( + body["access_token"], + key=self.provider.signing_key.public_key, + algorithms=[alg], + audience=self.provider.client_id, + ) + self.assertEqual(jwt["given_name"], self.user.name) + self.assertEqual(jwt["preferred_username"], self.user.username) + jwt = decode( + body["id_token"], + key=self.provider.signing_key.public_key, + algorithms=[alg], + audience=self.provider.client_id, + ) + self.assertEqual(jwt["given_name"], self.user.name) + self.assertEqual(jwt["preferred_username"], self.user.username) + def test_successful_password(self): """test successful (password grant)""" response = self.client.post( diff --git a/authentik/providers/oauth2/views/token.py b/authentik/providers/oauth2/views/token.py index 6281f5d085c4..f407e9295928 100644 --- a/authentik/providers/oauth2/views/token.py +++ b/authentik/providers/oauth2/views/token.py @@ -340,7 +340,7 @@ def __post_init_client_credentials_creds( if not user: raise TokenError("invalid_grant") token: Token = Token.filter_not_expired( - key=password, intent=TokenIntents.INTENT_APP_PASSWORD + key=password, intent=TokenIntents.INTENT_APP_PASSWORD, user=user ).first() if not token or token.user.uid != user.uid: raise TokenError("invalid_grant")