diff --git a/example/flask_op/views.py b/example/flask_op/views.py index 648c3de..1852881 100644 --- a/example/flask_op/views.py +++ b/example/flask_op/views.py @@ -18,8 +18,8 @@ import werkzeug from oidcop.exception import FailedAuthentication -from oidcop.exception import InvalidClient -from oidcop.exception import UnknownClient +from oidcop.exception import ClientAuthenticationError +from oidcop.exception import TokenAuthenticationError from oidcop.oidc.token import Token # logger = logging.getLogger(__name__) @@ -224,12 +224,18 @@ def service_endpoint(endpoint): if request.method == 'GET': try: req_args = endpoint.parse_request(request.args.to_dict(), http_info=http_info) - except (InvalidClient, UnknownClient) as err: + except ClientAuthenticationError as err: _log.error(err) return make_response(json.dumps({ 'error': 'unauthorized_client', 'error_description': str(err) - }), 400) + }), 401) + except TokenAuthenticationError as err: + _log.error(err) + return make_response(json.dumps({ + 'error': 'invalid_token', + 'error_description': str(err) + }), 401) except Exception as err: _log.error(err) return make_response(json.dumps({ diff --git a/src/oidcop/client_authn.py b/src/oidcop/client_authn.py index 8c540b0..a34e632 100755 --- a/src/oidcop/client_authn.py +++ b/src/oidcop/client_authn.py @@ -19,6 +19,7 @@ from oidcop import JWT_BEARER from oidcop import sanitize from oidcop.endpoint_context import EndpointContext +from oidcop.exception import BearerTokenAuthenticationError from oidcop.exception import InvalidClient from oidcop.exception import MultipleUsage from oidcop.exception import NotForMe @@ -406,15 +407,15 @@ def verify_client( elif not client_id and get_client_id_from_token: if not _token: logger.warning("No token") - raise ValueError("No token") + raise BearerTokenAuthenticationError("No token") try: # get_client_id_from_token is a callback... Do not abuse for code readability. auth_info["client_id"] = get_client_id_from_token(endpoint_context, _token, request) except ToOld: - raise ValueError("Expired token") + raise BearerTokenAuthenticationError("Expired token") except KeyError: - raise ValueError("Unknown token") + raise BearerTokenAuthenticationError("Unknown token") return auth_info diff --git a/src/oidcop/endpoint.py b/src/oidcop/endpoint.py index 2b98815..369940b 100755 --- a/src/oidcop/endpoint.py +++ b/src/oidcop/endpoint.py @@ -175,7 +175,6 @@ def parse_request( req = self.request_cls() # Verify that the client is allowed to do this - _client_id = "" auth_info = self.client_authentication(req, http_info, endpoint=self, **kwargs) if "client_id" in auth_info: @@ -206,14 +205,6 @@ def parse_request( request=req, client_id=_client_id, http_info=http_info, **kwargs ) - def get_client_id_from_token( - self, - endpoint_context: EndpointContext, - token: str, - request: Optional[Union[Message, dict]] = None, - ): - return "" - def client_authentication(self, request: Message, http_info: Optional[dict] = None, **kwargs): """ Do client authentication @@ -230,7 +221,7 @@ def client_authentication(self, request: Message, http_info: Optional[dict] = No endpoint_context=self.server_get("endpoint_context"), request=request, http_info=http_info, - get_client_id_from_token=self.get_client_id_from_token, + get_client_id_from_token=getattr(self, "get_client_id_from_token", None), **kwargs ) diff --git a/src/oidcop/exception.py b/src/oidcop/exception.py index fcbe4b2..eb500cf 100755 --- a/src/oidcop/exception.py +++ b/src/oidcop/exception.py @@ -58,15 +58,23 @@ class RedirectURIError(OidcEndpointError): pass -class UnknownClient(OidcEndpointError): +class ClientAuthenticationError(OidcEndpointError): pass -class InvalidClient(OidcEndpointError): +class UnknownClient(ClientAuthenticationError): pass -class UnAuthorizedClient(OidcEndpointError): +class InvalidClient(ClientAuthenticationError): + pass + + +class UnAuthorizedClient(ClientAuthenticationError): + pass + + +class BearerTokenAuthenticationError(OidcEndpointError): pass diff --git a/tests/test_26_oidc_userinfo_endpoint.py b/tests/test_26_oidc_userinfo_endpoint.py index 5c6a633..3ed37cc 100755 --- a/tests/test_26_oidc_userinfo_endpoint.py +++ b/tests/test_26_oidc_userinfo_endpoint.py @@ -12,6 +12,7 @@ from oidcop.configure import OPConfiguration from oidcop.cookie_handler import CookieHandler from oidcop.exception import ImproperlyConfigured +from oidcop.exception import BearerTokenAuthenticationError from oidcop.oidc import userinfo from oidcop.oidc.authorization import Authorization from oidcop.oidc.provider_config import ProviderConfiguration @@ -513,11 +514,8 @@ def mock(): monkeypatch.setattr("oidcop.token.utc_time_sans_frac", mock) - _req = self.endpoint.parse_request({}, http_info=http_info) - - assert _req.to_dict() == { - "error": "invalid_token", "error_description": "Expired token" - } + with pytest.raises(BearerTokenAuthenticationError): + self.endpoint.parse_request({}, http_info=http_info) def test_userinfo_claims(self): _acr = "https://refeds.org/profile/mfa"