Skip to content

Commit

Permalink
Convert JWT amr to list if string
Browse files Browse the repository at this point in the history
Apparently, this screws things up if drf-oidc-auth is below 1.0.0.
drf-oidc-auth >=1.0.0 is required for Django 4, however.
Bit of a workaround, but should work?
Source: #73 (comment)
  • Loading branch information
danipran committed Mar 30, 2023
1 parent 6cc124d commit 95a7421
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 6 deletions.
8 changes: 8 additions & 0 deletions helusers/_oidc_auth_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ def authenticate(self, request):
logger.debug("Invalid token signature")
raise

# Some OPs may provide the "amr" incorrectly as a string, while the
# specification dictates it must be an array of strings. Fix that here.
if isinstance(payload.get("amr"), str):
payload["amr"] = [payload["amr"]]
logger.debug(
'Modified "amr" claim to be an array of strings instead of a string.'
)

logger.debug("Token payload decoded as: {}".format(payload))

self.validate_claims(payload)
Expand Down
29 changes: 23 additions & 6 deletions helusers/tests/test_oidc_api_token_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,45 @@

from helusers.oidc import ApiTokenAuthentication

from .conftest import encoded_jwt_factory, ISSUER1
from .conftest import ISSUER1, encoded_jwt_factory


@pytest.fixture(autouse=True)
def auto_auth_server(auth_server):
return auth_server


@pytest.mark.django_db
def test_valid_jwt_is_accepted(rf, unix_timestamp_now):
sut = ApiTokenAuthentication()
@pytest.fixture
def user_uuid():
return uuid.UUID("b7a35517-eb1f-46c9-88bf-3206fb659c3c")

user_uuid = uuid.UUID("b7a35517-eb1f-46c9-88bf-3206fb659c3c")

encoded_jwt = encoded_jwt_factory(
@pytest.fixture
def jwt_data(user_uuid, unix_timestamp_now):
return dict(
iss=ISSUER1,
aud="test_audience",
iat=unix_timestamp_now - 10,
exp=unix_timestamp_now + 1000,
sub=str(user_uuid),
)


@pytest.mark.parametrize(
"jwt_data_extra",
[
dict(),
dict(amr="something"),
dict(amr=["something"]),
],
)
@pytest.mark.django_db
def test_valid_jwt_is_accepted(rf, jwt_data, user_uuid, jwt_data_extra):
sut = ApiTokenAuthentication()

jwt_data.update(jwt_data_extra)
encoded_jwt = encoded_jwt_factory(**jwt_data)

request = rf.get("/path", HTTP_AUTHORIZATION=f"Bearer {encoded_jwt}")

(user, auth) = sut.authenticate(request)
Expand Down

0 comments on commit 95a7421

Please sign in to comment.