Skip to content
This repository was archived by the owner on Jun 23, 2023. It is now read-only.

Commit 59c1ba7

Browse files
authored
Merge pull request #183 from nsklikas/feature-client-authn
Add more clear client/token authn exceptions
2 parents ec179bb + 22c6aba commit 59c1ba7

File tree

5 files changed

+29
-25
lines changed

5 files changed

+29
-25
lines changed

example/flask_op/views.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
import werkzeug
1919

2020
from oidcop.exception import FailedAuthentication
21-
from oidcop.exception import InvalidClient
22-
from oidcop.exception import UnknownClient
21+
from oidcop.exception import ClientAuthenticationError
22+
from oidcop.exception import TokenAuthenticationError
2323
from oidcop.oidc.token import Token
2424

2525
# logger = logging.getLogger(__name__)
@@ -224,12 +224,18 @@ def service_endpoint(endpoint):
224224
if request.method == 'GET':
225225
try:
226226
req_args = endpoint.parse_request(request.args.to_dict(), http_info=http_info)
227-
except (InvalidClient, UnknownClient) as err:
227+
except ClientAuthenticationError as err:
228228
_log.error(err)
229229
return make_response(json.dumps({
230230
'error': 'unauthorized_client',
231231
'error_description': str(err)
232-
}), 400)
232+
}), 401)
233+
except TokenAuthenticationError as err:
234+
_log.error(err)
235+
return make_response(json.dumps({
236+
'error': 'invalid_token',
237+
'error_description': str(err)
238+
}), 401)
233239
except Exception as err:
234240
_log.error(err)
235241
return make_response(json.dumps({

src/oidcop/client_authn.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from oidcop import JWT_BEARER
2020
from oidcop import sanitize
2121
from oidcop.endpoint_context import EndpointContext
22+
from oidcop.exception import BearerTokenAuthenticationError
2223
from oidcop.exception import InvalidClient
2324
from oidcop.exception import MultipleUsage
2425
from oidcop.exception import NotForMe
@@ -406,15 +407,15 @@ def verify_client(
406407
elif not client_id and get_client_id_from_token:
407408
if not _token:
408409
logger.warning("No token")
409-
raise ValueError("No token")
410+
raise BearerTokenAuthenticationError("No token")
410411

411412
try:
412413
# get_client_id_from_token is a callback... Do not abuse for code readability.
413414
auth_info["client_id"] = get_client_id_from_token(endpoint_context, _token, request)
414415
except ToOld:
415-
raise ValueError("Expired token")
416+
raise BearerTokenAuthenticationError("Expired token")
416417
except KeyError:
417-
raise ValueError("Unknown token")
418+
raise BearerTokenAuthenticationError("Unknown token")
418419

419420
return auth_info
420421

src/oidcop/endpoint.py

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,6 @@ def parse_request(
175175
req = self.request_cls()
176176

177177
# Verify that the client is allowed to do this
178-
_client_id = ""
179178
auth_info = self.client_authentication(req, http_info, endpoint=self, **kwargs)
180179

181180
if "client_id" in auth_info:
@@ -206,14 +205,6 @@ def parse_request(
206205
request=req, client_id=_client_id, http_info=http_info, **kwargs
207206
)
208207

209-
def get_client_id_from_token(
210-
self,
211-
endpoint_context: EndpointContext,
212-
token: str,
213-
request: Optional[Union[Message, dict]] = None,
214-
):
215-
return ""
216-
217208
def client_authentication(self, request: Message, http_info: Optional[dict] = None, **kwargs):
218209
"""
219210
Do client authentication
@@ -230,7 +221,7 @@ def client_authentication(self, request: Message, http_info: Optional[dict] = No
230221
endpoint_context=self.server_get("endpoint_context"),
231222
request=request,
232223
http_info=http_info,
233-
get_client_id_from_token=self.get_client_id_from_token,
224+
get_client_id_from_token=getattr(self, "get_client_id_from_token", None),
234225
**kwargs
235226
)
236227

src/oidcop/exception.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,23 @@ class RedirectURIError(OidcEndpointError):
5858
pass
5959

6060

61-
class UnknownClient(OidcEndpointError):
61+
class ClientAuthenticationError(OidcEndpointError):
6262
pass
6363

6464

65-
class InvalidClient(OidcEndpointError):
65+
class UnknownClient(ClientAuthenticationError):
6666
pass
6767

6868

69-
class UnAuthorizedClient(OidcEndpointError):
69+
class InvalidClient(ClientAuthenticationError):
70+
pass
71+
72+
73+
class UnAuthorizedClient(ClientAuthenticationError):
74+
pass
75+
76+
77+
class BearerTokenAuthenticationError(OidcEndpointError):
7078
pass
7179

7280

tests/test_26_oidc_userinfo_endpoint.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from oidcop.configure import OPConfiguration
1313
from oidcop.cookie_handler import CookieHandler
1414
from oidcop.exception import ImproperlyConfigured
15+
from oidcop.exception import BearerTokenAuthenticationError
1516
from oidcop.oidc import userinfo
1617
from oidcop.oidc.authorization import Authorization
1718
from oidcop.oidc.provider_config import ProviderConfiguration
@@ -513,11 +514,8 @@ def mock():
513514

514515
monkeypatch.setattr("oidcop.token.utc_time_sans_frac", mock)
515516

516-
_req = self.endpoint.parse_request({}, http_info=http_info)
517-
518-
assert _req.to_dict() == {
519-
"error": "invalid_token", "error_description": "Expired token"
520-
}
517+
with pytest.raises(BearerTokenAuthenticationError):
518+
self.endpoint.parse_request({}, http_info=http_info)
521519

522520
def test_userinfo_claims(self):
523521
_acr = "https://refeds.org/profile/mfa"

0 commit comments

Comments
 (0)