-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ [#83] Implement JWT user-info response data processing
- Loading branch information
1 parent
f37648c
commit 68f9742
Showing
8 changed files
with
583 additions
and
41 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
""" | ||
Support for user info JWT verification and decoding. | ||
The bulk of the implementation is taken from mozilla-django-oidc where the access token | ||
is processed, but adapted for non-hardcoded/configured parameters. | ||
In the case of Keycloak for example, the token signing algorithm is configured on the | ||
server and can change on a whim. | ||
""" | ||
|
||
import json | ||
from typing import Any | ||
|
||
from django.core.exceptions import SuspiciousOperation | ||
from django.utils.encoding import smart_bytes | ||
|
||
from josepy.jwk import JWK | ||
from josepy.jws import JWS | ||
|
||
|
||
def verify_and_decode_token(token: bytes, key) -> dict[str, Any]: | ||
""" | ||
Verify that the token was not tampered with and if okay, return the payload. | ||
This is mostly taken from | ||
:meth:`mozilla_django_oidc.auth.OIDCAuthenticationBackend._verify_jws`. | ||
""" | ||
|
||
jws = JWS.from_compact(token) | ||
|
||
# validate the signing algorithm | ||
if (alg := jws.signature.combined.alg) is None: | ||
raise SuspiciousOperation("No alg value found in header") | ||
|
||
# one of the most common implementation weaknesses -> attacker can supply 'none' | ||
# algorithm | ||
if alg.name == "none": | ||
raise SuspiciousOperation("'none' for alg value is not allowed") | ||
|
||
# process key parameter which was/may have been loaded from keys endpoint. I'm u | ||
# Unsure what the type of this parameter can be :/ | ||
match key: | ||
case str(): | ||
jwk = JWK.load(smart_bytes(key)) | ||
case _: | ||
jwk = JWK.from_json(key) | ||
# address some missing upstream Self type declarations | ||
assert isinstance(jwk, JWK) | ||
|
||
if not jws.verify(jwk): | ||
raise SuspiciousOperation("JWS token verification failed.") | ||
|
||
return json.loads(jws.payload.decode("utf-8")) |
Oops, something went wrong.