diff --git a/oidc_provider/lib/endpoints/token.py b/oidc_provider/lib/endpoints/token.py index 2a687f5..b12ecaf 100644 --- a/oidc_provider/lib/endpoints/token.py +++ b/oidc_provider/lib/endpoints/token.py @@ -33,7 +33,8 @@ class TokenEndpoint(object): self.params.client_id = client_id self.params.client_secret = client_secret - self.params.redirect_uri = unquote(self.request.POST.get('redirect_uri', '')) + self.params.redirect_uri = unquote( + self.request.POST.get('redirect_uri', '').split('?', 1)[0]) self.params.grant_type = self.request.POST.get('grant_type', '') self.params.code = self.request.POST.get('code', '') self.params.state = self.request.POST.get('state', '') diff --git a/oidc_provider/tests/test_token_endpoint.py b/oidc_provider/tests/test_token_endpoint.py index 652d8ad..bdafb48 100644 --- a/oidc_provider/tests/test_token_endpoint.py +++ b/oidc_provider/tests/test_token_endpoint.py @@ -271,6 +271,29 @@ class TokenTestCase(TestCase): False, msg='Client authentication fails using HTTP Basic Auth.') + def test_client_redirect_url(self): + """ + Validate that client redirect URIs with query strings match registered + URIs, and that unregistered URIs are rejected. + """ + SIGKEYS = self._get_keys() + code = self._create_code() + post_data = self._auth_code_post_data(code=code.code) + + # Unregistered URI + post_data['redirect_uri'] = 'http://invalid.example.org' + + response = self._post_request(post_data) + + self.assertIn('invalid_client', response.content.decode('utf-8')), + + # Registered URI contained a query string + post_data['redirect_uri'] = 'http://example.com/?client=OidcClient' + + response = self._post_request(post_data) + + self.assertNotIn('invalid_client', response.content.decode('utf-8')), + def test_access_token_contains_nonce(self): """ If present in the Authentication Request, Authorization Servers MUST