#Authentication Indefinetly hangs when running on AWS but not Local

9 messages · Page 1 of 1 (latest)

fallow parrot
#

Hi, not sure if this is the correct place but I have been stuck on an issue where my authentication hangs indefinitely without an explicit error when running my Django app on AWS. I feel like I am probably missing something obvious or I have made a simple mistake.

My application is in django 4.2.2, When running the implementation locally it works fine.
I have tried to strip back my authentication implementation to try discover what is wrong. I have also executed this via Django shell to validate where the error seems to be occurring.

I have managed to narrow down that the login hangs when sending a signal, this is from django.contrib.auth import login when the method executes user_logged_in.send(sender=user.__class__, request=request, user=user) where from django.contrib.auth.signals import user_logged_in.

I can confirm it indefinitely hangs when:

  • trying to login via the site on the login page and admin login
  • when creating a super user ( but the user gets created)
  • when executing via the shell

My AWS set up tries to stay within free tier, so my application is deployed using ECS into the public subnet and traffic is routed via an application load balancer. I have no trouble reaching the site when it is running but it hangs when I successfully login (incorrect passwords will display a message). To try and avoid any network interference I have ssh'ed into the box and executed code line by line within the django shell.

Note: I have used django cookie cutter to build the application but stripped out all_auth as I hit a similar issue.

#

This is what I executed in the shell:

from django.contrib.auth import authenticate, login
from django.contrib.sessions.middleware import SessionMiddleware
from django.test import RequestFactory
from django.contrib.auth import SESSION_KEY, BACKEND_SESSION_KEY, HASH_SESSION_KEY, get_user_model
from django.contrib.auth import _get_user_session_key
from django.contrib.auth import constant_time_compare
from django.contrib.auth.signals import user_logged_in
from django.middleware.csrf import rotate_token

User = get_user_model()
User.objects.all() # check user is in DB

factory = RequestFactory()
request = factory.post('/login/')

middleware = SessionMiddleware(lambda req: None)
middleware.process_request(request)
request.session.save()

user = authenticate(username="[email protected]", password="Pa55word!")
user # check that there is a user

# login(request, user) # hangs indefinetly 

# breakdown login execution from https://github.com/django/django/blob/main/django/contrib/auth/__init__.py

session_auth_hash = user.get_session_auth_hash()

if SESSION_KEY in request.session:
  if _get_user_session_key(request) != user.pk or (
      session_auth_hash
      and not constant_time_compare(
          request.session.get(HASH_SESSION_KEY, ""), session_auth_hash
      )
  ): 
    request.session.flush()
else: 
  request.session.cycle_key()

request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
request.session[BACKEND_SESSION_KEY] = 'django.contrib.auth.backends.ModelBackend'
request.session[HASH_SESSION_KEY] = session_auth_hash

rotate_token(request)
user_logged_in.send(sender=user.__class__, request=request, user=user)
#

This is my current settings in regards to auth:

AUTHENTICATION_BACKENDS = ["django.contrib.auth.backends.ModelBackend",]
AUTH_USER_MODEL = "users.User"
LOGIN_REDIRECT_URL = "users:redirect"
LOGIN_URL = "users:login"
SESSION_COOKIE_HTTPONLY = True
CSRF_COOKIE_HTTPONLY = True
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = False
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
USE_X_FORWARDED_HOST = True
winter cloak
#

Probably not related, but why not 4.2.18?

fallow parrot
#

I have been start stop on this project, so I haven't upgraded the version. I'll do that now to get it out of the way.

fallow parrot
#

I can confirm that after an update the issue still persists. I guess I should dig further into how signals functions and why they could hang.
Although haven't found anything obvious so far. I would guess as it is on AWS it would be network but I have set my security groups to 0.0.0.0/0 and testing within the application. Obviously db shouldn't be the issue either as the user exists in the db and I can see sessions when I manually create them.

winter cloak
#

Are you using signals anywhere? Is anything listening to that signal?

fallow parrot
#

At this moment no, this is a default one which exists for auth:

for receiver in user_logged_in.receivers:
  print(receiver)

gives
(('update_last_login', 000000000000), <weakref at 0x; to 'function' at 0x (update_last_login)>)

So in my case it seems to either hang with the signalling fucntionality or the reciever update_last_login. I haven't started to dig that far as I felt like I was in a rabbit hole and should check with others.

fallow parrot
#

Is the fact I get False when I try disconnect the reciever for this signal a sign of any issue? I cannot seem to find any indication of any issues, I can authetnicate, create sessions in the db so I would be surprised if this is a db level issue.

from django.contrib.auth.models import update_last_login
from django.contrib.auth.signals import user_logged_in

user_logged_in.disconnect(update_last_login)

I also ensured that I was running on minimal middleware:

MIDDLEWARE = [
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
]