ForestAdmin / django-forestadmin

🐍 Django agent for Forest Admin to integrate directly to your existing Django backend application.
https://www.forestadmin.com
GNU General Public License v3.0
122 stars 18 forks source link

IATError: Issued in the future #108

Closed rmartin48 closed 2 years ago

rmartin48 commented 2 years ago

Expected behavior

Forest Admin authentication should work consistently.

Actual behavior

Authentication fails on an intermittent basis due to a race condition when issuing the id token. When this happens, the /forest/authentication/callback endpoint will return a 500 error with an oic.oic.message.IATError: Issued in the future exception raised. Clicking Login in again multiple times usually resolves the issue.

Debugging the token verification process in oic reveals a very small discrepancy between _now and _iat. The intermittent nature of the bug suggest this discrepancy is not always present.

# oic/oic/message.py

class IdToken(OpenIDSchema):
    ...
    if _now < (_iat - _skew):  # e.g. 1657294222 < (1657294223 - 0)
        raise IATError("Issued in the future")
Screen Shot 2022-07-09 at 1 36 08 am

Failure Logs

ERROR:django.request:Internal Server Error: /forest/authentication/callback
Traceback (most recent call last):
  File "/app/.venv/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/app/.venv/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/app/.venv/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/app/.venv/lib/python3.9/site-packages/django/views/generic/base.py", line 98, in dispatch
    return handler(request, *args, **kwargs)
  File "/app/.venv/lib/python3.9/site-packages/django_forest/authentication/utils.py", line 21, in wrapper
    return f(*args, **kwargs)
  File "/app/.venv/lib/python3.9/site-packages/django_forest/authentication/views/callback.py", line 149, in get
    token_body = self._verify_code_and_generate_token_body(callback_url, request)
  File "/app/.venv/lib/python3.9/site-packages/django_forest/authentication/views/callback.py", line 131, in _verify_code_and_generate_token_body
    user = self._authenticate(
  File "/app/.venv/lib/python3.9/site-packages/django_forest/authentication/views/callback.py", line 90, in _authenticate
    access_token_request = client.do_access_token_request(
  File "/app/.venv/lib/python3.9/site-packages/oic/oic/__init__.py", line 704, in do_access_token_request
    atr = super().do_access_token_request(
  File "/app/.venv/lib/python3.9/site-packages/oic/oauth2/__init__.py", line 926, in do_access_token_request
    return self.request_and_return(
  File "/app/.venv/lib/python3.9/site-packages/oic/oauth2/__init__.py", line 819, in request_and_return
    return self.parse_request_response(resp, response, body_type, state, **kwargs)
  File "/app/.venv/lib/python3.9/site-packages/oic/oauth2/__init__.py", line 760, in parse_request_response
    return self.parse_response(
  File "/app/.venv/lib/python3.9/site-packages/oic/oauth2/__init__.py", line 679, in parse_response
    verf = resp.verify(**kwargs)
  File "/app/.venv/lib/python3.9/site-packages/oic/oic/message.py", line 360, in verify
    self["id_token"] = verify_id_token(self, **kwargs)
  File "/app/.venv/lib/python3.9/site-packages/oic/oic/message.py", line 311, in verify_id_token
    if not idt.verify(**kwargs):
  File "/app/.venv/lib/python3.9/site-packages/oic/oic/message.py", line 790, in verify
    raise IATError("Issued in the future")
oic.oic.message.IATError: Issued in the future

Proposed fix

Passing in a skew to oic addresses the race condition.

# django_forest/authentication/views/callback.py

class CallbackView(View):
    def _authenticate(self, client, state, code):
        access_token_request = client.do_access_token_request(
            ...,
            skew=10
        )

Context

vamonte commented 2 years ago

@rmartin48 Thank's, I'll check you PR today.