authentik icon indicating copy to clipboard operation
authentik copied to clipboard

OAuth2/OpenID custom mapping can't serialize python set to JSON

Open Argon42043 opened this issue 8 months ago • 1 comments

Describe the bug When using a python set for property scope mapping, everything seems fine. Authentik displays the property mapping in the test screen correctly. Also in the provider Preview the JWT payload is shown correctly. But when actually requesting an authentication token, the request fails due to a serialization error. Furthermore, there's no entry in the event log.

To Reproduce Steps to reproduce the behavior:

  1. Create an OAuth2/OpenID provider and application
  2. Create a new custom claim using a python set in the expression return value
return {
  "test": set()
}
  1. Assign the claim to the provider
  2. Request an actual token from an external application
  3. Error will be shown in the Authentik logs.

Expected behavior

  • Get an event log entry
  • Consistent behavior between what Authentik shows and what it actually does
  • Serialize python sets consistently

Screenshots Screenshot 1 Screenshot 2 Screenshot 3

Logs

INF action=system_exception auth_via=oauth_client_secret client_ip=192.168.100.1 context={"http_request":{"args":{},"method":"POST","path":"/application/o/token/","user_agent":"Dalvik/2.1.0 (Linux; U; Android 14; SM-A145R Build/UP1A.231005.007)"},"message":"Traceback (most recent call last):\n  File \"/ak-root/venv/lib/python3.12/site-packages/asgiref/sync.py\", line 518, in thread_handler\n    raise exc_info[1]\n  File \"/ak-root/venv/lib/python3.12/site-packages/django/core/handlers/base.py\", line 253, in _get_response_async\n    response = await wrapped_callback(\n               ^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/ak-root/venv/lib/python3.12/site-packages/asgiref/sync.py\", line 468, in __call__\n    ret = await asyncio.shield(exec_coro)\n          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/ak-root/venv/lib/python3.12/site-packages/asgiref/current_thread_executor.py\", line 40, in run\n    result = self.fn(*self.args, **self.kwargs)\n             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/ak-root/venv/lib/python3.12/site-packages/asgiref/sync.py\", line 522, in thread_handler\n    return func(*args, **kwargs)\n           ^^^^^^^^^^^^^^^^^^^^^\n  File \"/ak-root/venv/lib/python3.12/site-packages/sentry_sdk/integrations/django/views.py\", line 84, in sentry_wrapped_callback\n    return callback(request, *args, **kwargs)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/ak-root/venv/lib/python3.12/site-packages/django/views/generic/base.py\", line 104, in view\n    return self.dispatch(request, *args, **kwargs)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/ak-root/venv/lib/python3.12/site-packages/django/utils/decorators.py\", line 48, in _wrapper\n    return bound_method(*args, **kwargs)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/ak-root/venv/lib/python3.12/site-packages/django/views/decorators/csrf.py\", line 65, in _view_wrapper\n    return view_func(request, *args, **kwargs)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/authentik/providers/oauth2/views/token.py\", line 498, in dispatch\n    response = super().dispatch(request, *args, **kwargs)\n               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/ak-root/venv/lib/python3.12/site-packages/django/views/generic/base.py\", line 143, in dispatch\n    return handler(request, *args, **kwargs)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/authentik/providers/oauth2/views/token.py\", line 527, in post\n    return TokenResponse(self.create_code_response())\n                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/authentik/providers/oauth2/views/token.py\", line 562, in create_code_response\n    access_token.id_token = access_id_token\n    ^^^^^^^^^^^^^^^^^^^^^\n  File \"/authentik/providers/oauth2/models.py\", line 369, in id_token\n    self.token = value.to_access_token(self.provider)\n                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/authentik/providers/oauth2/id_token.py\", line 163, in to_access_token\n    return provider.encode(final)\n           ^^^^^^^^^^^^^^^^^^^^^^\n  File \"/authentik/providers/oauth2/models.py\", line 284, in encode\n    return encode(payload, key, algorithm=alg, headers=headers)\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/ak-root/venv/lib/python3.12/site-packages/jwt/api_jwt.py\", line 67, in encode\n    json_payload = self._encode_payload(\n                   ^^^^^^^^^^^^^^^^^^^^^\n  File \"/ak-root/venv/lib/python3.12/site-packages/jwt/api_jwt.py\", line 94, in _encode_payload\n    return json.dumps(\n           ^^^^^^^^^^^\n  File \"/usr/local/lib/python3.12/json/__init__.py\", line 238, in dumps\n    **kw).encode(obj)\n          ^^^^^^^^^^^\n  File \"/usr/local/lib/python3.12/json/encoder.py\", line 200, in encode\n    chunks = self.iterencode(o, _one_shot=True)\n             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/usr/local/lib/python3.12/json/encoder.py\", line 258, in iterencode\n    return _iterencode(o, 0)\n           ^^^^^^^^^^^^^^^^^\n  File \"/usr/local/lib/python3.12/json/encoder.py\", line 180, in default\n    raise TypeError(f'Object of type {o.__class__.__name__} '\nbuiltins.TypeError: Object of type set is not JSON serializable"} domain_url=dev-authentik.gaslightinglabs.com event=Created Event host=dev-authentik.gaslightinglabs.com logger=authentik.events.models pid=53 request_id=96eb09aebfce40f488c234a943f5b937 schema_name=public timestamp=2024-06-25T07:26:54.142573 user={"email":"","is_anonymous":true,"pk":1,"username":"AnonymousUser"}

Version and Deployment (please complete the following information):

  • authentik version: 2024.4.2
  • Deployment: docker-compose

Additional context The client used to request the token is an android app using the official openid/AppAuth-Android SDK

Argon42043 avatar Jun 25 '24 07:06 Argon42043