From e264c07f03ba6f2d36058800271174d28890c79c Mon Sep 17 00:00:00 2001 From: bull500 Date: Wed, 31 May 2023 06:35:48 +0530 Subject: [PATCH 1/2] Initial commit with Patch & testcases --- AUTHORS | 1 + CHANGELOG.md | 1 + oauth2_provider/oauth2_validators.py | 2 +- tests/test_oauth2_validators.py | 24 ++++++++++++++++++++++++ 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 507ef29fd..4be6ac505 100644 --- a/AUTHORS +++ b/AUTHORS @@ -9,6 +9,7 @@ Contributors Abhishek Patel Adam Johnson +Adheeth P Praveen Alan Crosswell Alejandro Mantecon Guillen Aleksander Vaskevich diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a135d2a6..8ab83f6ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * #1218 Confim support for Python 3.11. * #1222 Remove expired ID tokens alongside access tokens in `cleartokens` management command * #1270 Fix RP-initiated Logout with no available Django session +* #1092 Allow Authorization Code flow without a client_secret ## [2.2.0] 2022-10-18 diff --git a/oauth2_provider/oauth2_validators.py b/oauth2_provider/oauth2_validators.py index 3e921ec99..ecff21880 100644 --- a/oauth2_provider/oauth2_validators.py +++ b/oauth2_provider/oauth2_validators.py @@ -170,7 +170,7 @@ def _authenticate_request_body(self, request): # TODO: check if oauthlib has already unquoted client_id and client_secret try: client_id = request.client_id - client_secret = request.client_secret + client_secret = getattr(request, "client_secret", "") except AttributeError: return False diff --git a/tests/test_oauth2_validators.py b/tests/test_oauth2_validators.py index 2c062d616..83cf770e4 100644 --- a/tests/test_oauth2_validators.py +++ b/tests/test_oauth2_validators.py @@ -30,6 +30,7 @@ RefreshToken = get_refresh_token_model() CLEARTEXT_SECRET = "1234567890abcdefghijklmnopqrstuvwxyz" +CLEARTEXT_BLANK_SECRET = "" @contextlib.contextmanager @@ -61,11 +62,25 @@ def setUp(self): ) self.request.client = self.application + self.blank_secret_request = mock.MagicMock(wraps=Request) + self.blank_secret_request.user = self.user + self.blank_secret_request.grant_type = "not client" + self.blank_secret_application = Application.objects.create( + client_id="blank_secret_client_id", + client_secret=CLEARTEXT_BLANK_SECRET, + user=self.user, + client_type=Application.CLIENT_PUBLIC, + authorization_grant_type=Application.GRANT_PASSWORD, + ) + self.blank_secret_request.client = self.blank_secret_application + def tearDown(self): self.application.delete() def test_authenticate_request_body(self): self.request.client_id = "client_id" + self.assertFalse(self.validator._authenticate_request_body(self.request)) + self.request.client_secret = "" self.assertFalse(self.validator._authenticate_request_body(self.request)) @@ -75,6 +90,15 @@ def test_authenticate_request_body(self): self.request.client_secret = CLEARTEXT_SECRET self.assertTrue(self.validator._authenticate_request_body(self.request)) + self.blank_secret_request.client_id = "blank_secret_client_id" + self.assertTrue(self.validator._authenticate_request_body(self.blank_secret_request)) + + self.blank_secret_request.client_secret = CLEARTEXT_BLANK_SECRET + self.assertTrue(self.validator._authenticate_request_body(self.blank_secret_request)) + + self.blank_secret_request.client_secret = "wrong_client_secret" + self.assertFalse(self.validator._authenticate_request_body(self.blank_secret_request)) + def test_extract_basic_auth(self): self.request.headers = {"HTTP_AUTHORIZATION": "Basic 123456"} self.assertEqual(self.validator._extract_basic_auth(self.request), "123456") From 3ee6e662cda2c8738c25abfed4b6e0698948dcab Mon Sep 17 00:00:00 2001 From: Alan Crosswell Date: Wed, 31 May 2023 09:58:50 -0400 Subject: [PATCH 2/2] reference the RFC where empty client secret is allowed --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ab83f6ce..eed4b8b9d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * #1218 Confim support for Python 3.11. * #1222 Remove expired ID tokens alongside access tokens in `cleartokens` management command * #1270 Fix RP-initiated Logout with no available Django session -* #1092 Allow Authorization Code flow without a client_secret +* #1092 Allow Authorization Code flow without a client_secret per [RFC 6749 2.3.1](https://www.rfc-editor.org/rfc/rfc6749.html#section-2.3.1) ## [2.2.0] 2022-10-18