From e11e1400d91be39c247298286ad84a5c516e3988 Mon Sep 17 00:00:00 2001 From: Pieter Ennes Date: Thu, 23 Feb 2017 16:42:09 +0000 Subject: [PATCH 1/2] Improve prompt parameter validation. - Strip leading and trailng spaces. - Disallow prompt=none with other values as per spec. - Pass to credentials as a set. --- .../rfc6749/grant_types/openid_connect.py | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/oauthlib/oauth2/rfc6749/grant_types/openid_connect.py b/oauthlib/oauth2/rfc6749/grant_types/openid_connect.py index 025d368b..12d4a867 100644 --- a/oauthlib/oauth2/rfc6749/grant_types/openid_connect.py +++ b/oauthlib/oauth2/rfc6749/grant_types/openid_connect.py @@ -275,14 +275,26 @@ def openid_authorization_validator(self, request): if not request.scopes or 'openid' not in request.scopes: return {} - # prompt other than 'none' should be handled by the server code that uses oauthlib - if request.prompt == 'none' and not request.id_token_hint: - msg = "Prompt is set to none yet id_token_hint is missing." - raise InvalidRequestError(request=request, description=msg) + prompt = request.prompt if request.prompt else [] + if hasattr(prompt, 'split'): + prompt = prompt.strip().split() + prompt = set(prompt) + + if 'none' in prompt: + + if len(prompt) > 1: + msg = "Prompt none is mutually exclusive with other values." + raise InvalidRequestError(request=request, description=msg) + + # prompt other than 'none' should be handled by the server code that + # uses oauthlib + if not request.id_token_hint: + msg = "Prompt is set to none yet id_token_hint is missing." + raise InvalidRequestError(request=request, description=msg) - if request.prompt == 'none': if not self.request_validator.validate_silent_login(request): raise LoginRequired(request=request) + if not self.request_validator.validate_silent_authorization(request): raise ConsentRequired(request=request) @@ -293,12 +305,6 @@ def openid_authorization_validator(self, request): msg = "Session user does not match client supplied user." raise LoginRequired(request=request, description=msg) - prompt = [] - if request.prompt: - prompt = request.prompt - if hasattr(prompt, 'split'): - prompt = prompt.split() - request_info = { 'display': request.display, 'prompt': prompt, @@ -335,6 +341,7 @@ def openid_implicit_authorization_validator(self, request): return {'nonce': request.nonce, 'claims': request.claims} + class OpenIDConnectAuthCode(OpenIDConnectBase): def __init__(self, request_validator=None, **kwargs): From 84805f1929e4e83f24de2e8d7c47f2d0645ca52f Mon Sep 17 00:00:00 2001 From: Pieter Ennes Date: Sun, 2 Apr 2017 15:29:29 +0100 Subject: [PATCH 2/2] Add test for prompt=none exclusiveness. --- .../rfc6749/endpoints/test_prompt_handling.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/oauth2/rfc6749/endpoints/test_prompt_handling.py b/tests/oauth2/rfc6749/endpoints/test_prompt_handling.py index bad424fe..b5a51ebf 100644 --- a/tests/oauth2/rfc6749/endpoints/test_prompt_handling.py +++ b/tests/oauth2/rfc6749/endpoints/test_prompt_handling.py @@ -7,10 +7,12 @@ import mock from ....unittest import TestCase +from oauthlib.oauth2 import InvalidRequestError from oauthlib.oauth2.rfc6749.tokens import BearerToken from oauthlib.oauth2.rfc6749.grant_types import OpenIDConnectAuthCode from oauthlib.oauth2.rfc6749.endpoints.authorization import AuthorizationEndpoint + class OpenIDConnectEndpointTest(TestCase): def setUp(self): @@ -48,3 +50,19 @@ def test_authorization_endpoint_handles_prompt(self, generate_token): self.assertURLEqual(h['Location'], expected) self.assertEqual(b, None) self.assertEqual(s, 302) + + def test_prompt_none_exclusiveness(self): + """ + Test that prompt=none can't be used with another prompt value. + """ + params = { + 'prompt': 'none consent', + 'state': 'abc', + 'redirect_uri': 'https://a.b/cb', + 'response_type': 'code', + 'client_id': 'abcdef', + 'scope': 'hello openid' + } + url = 'http://a.b/path?' + urlencode(params) + with self.assertRaises(InvalidRequestError): + self.endpoint.validate_authorization_request(url)