I’ve built an app that uses a custom authentication backend because I needed to integrate ldap. It works when authenticating into the admin console, but doesn’t on my app.
The issue
After hitting the submit button on the login page, I am redirected back to the login page even if the authentication was successful.
My troubleshooting
-
I am implementing class-based views and using the LoginRequiredMixin. I thought this was causing a redirection loop back to login, so I removed it. I’m no longer being redirected back to login, but using {{ user.is_authenticated }} within my index page tells me that the user isn’t being “logged in”. I found that this wasn’t the cause so I added the mixin back in.
-
I’ve double-checked the methods within the custom backend to ensure they’re working like Django’s backend, but haven’t seen any errors.
-
I’ve also found that request.user returns Anonymous User, but within the request.session, the _auth_user_id returns the authenticated user. It seems like there’s a disconnect between the request user and auth user.
Please let me know what information you need to help me troubleshoot.
Thank you!
Custom Backend Code
class LDAPAuthBackend(BaseBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
# will validate if the user exists in ldap
user_exists = ldap.check_user_exists(username, "username")
if user_exists[0]:
user = None
domain = user_exists[1]
# checking to see if the user exists in the database, if not, create them
try:
user = User.objects.get(username=username)
ldap_data = ldap.ldap_login(username, password, domain)
if not ldap_data[0]:
return None
return user
except User.DoesNotExist:
# create a new user if they authenticate
# getting ldap data to create them in the system
ldap_data = ldap.ldap_login(username, password, user_exists[1])
if ldap_data[0]:
user_data = ldap_data[1]
user = User(
username=user_data["username"],
email=user_data["email"],
first_name=user_data["first_name"],
last_name=user_data["last_name"],
is_staff=True,
is_superuser=True if user_data["username"].lower() in settings.WEB_STAFF else False
)
user.set_unusable_password()
user.save()
return user
return None
def get_user(self, user_id):
try:
return User.objects.get(id=user_id)
except ObjectDoesNotExist:
return None
Login View Code
class UserLogin(View):
title = "Login "
template = "ipa/user-login.html"
def get(self, request):
print(request.user)
if request.user.is_authenticated:
return redirect("index")
else:
form = CustomLoginForm()
context = {
"title": self.title,
"form": form,
"next": request.GET.get("next"),
}
return render(request, self.template, context)
def post(self, request):
form = CustomLoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get("username")
password = form.cleaned_data.get("password")
# authenticate user
user = ldap.authenticate(self.request, username=username, password=password)
# user = authenticate(self.request, username=username, password=password)
# login user
if user is not None and user.is_active:
login(self.request, user, backend="core.backends.LDAPBackend")
index_urls = ["/", "/ipa/"]
redirect_to = request.GET.get("next") if request.GET.get("next") not in index_urls and not None else "index"
if redirect_to == "None":
redirect_to = "index"
print(request.user.is_authenticated)
return redirect(redirect_to)
# return HttpResponseRedirect(reverse_lazy('index'))
else:
messages.add_message(request, messages.ERROR, "Username or password is incorrect\nUse Active directory credentials.")
return redirect("login")