How can I authenticate and login the user from Active Directory? This is my code
Authenticate.py:
from .models import User
from ldap3 import ALL, Server, Connection, NTLM
from ldap3.core.exceptions import LDAPException
from django.contrib.auth.backends import ModelBackend
def validate_user_credentials(username, password):
server = Server(host='#xxxDomain',
use_ssl=False, get_info=ALL)
try:
with Connection(
server, authentication="NTLM", user=f"{''}\\{username}", password=password, raise_exceptions=False,
) as connection:
print(connection.result['description'])
return True
except LDAPException as e:
print(e)
return False
class UserAuth(ModelBackend):
def authenticate(self,request,username=None,password=None,**kwargs):
try:
if (validate_user_credentials(username, password)):
print("Helloooooooooooooo")
user = User.objects.get(username=username)
print(user)
return user
return None
except User.DoesNotExist:
return None
def get_user(self, user_id):
try:
return User.objects.get(username=user_id)
except User.DoesNotExist:
return None
views.py:
class UserLoginView(View):
form_class = UserLoginForm
def get(self, request):
form = self.form_class
return render(request, 'login/login.html', {'form': form})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
cd = form.cleaned_data
userexistindb = User.objects.filter(
username=cd['username'], is_user_local=False).exists()
username = cd['username']
password = cd['password']
try:
if userexistindb:
try:
user = authenticate(
request, username=username, password=password)
if (user is not None):
login(request=request, user=user)
messages.success(
request, 'Loged in success', 'success')
return redirect('login:result')
else:
messages.error(request, 'us', 'warning')
except User.DoesNotExist:
messages.error(
request, 'Invalid User/Password', 'warning')
except User.DoesNotExist:
username = None
messages.error(
request, 'Invalid User/Password', 'warning')
return render(request, 'login/login.html', {'form': form})
The result is the sessionid It is created,The username and password
are correct and the answer is correct
but the captured user information is not displayed. Information is
displayed in the log!
enter image description here
What should I do!
Related
Why when i desactive user on Django admin site in my class in post method
requirement return negative first if requirement user is not None ?
Probably if user desative true Django don`t look him in user table ?
class LoginView(View):
template_name = 'login.html'
def get(self, request):
form = LoginForm()
return render(request, self.template_name, locals())
def post(self, request):
form = LoginForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return redirect('home')
else:
alert = messages.error(request, 'Twoje konto zostało zablokowane!')
return render(request, self.template_name, locals())
else:
alert = messages.error(request, 'Błędna nazwa użytkownika!')
return render(request, self.template_name, locals())
In authenticate function, django call authenticate on your AUTHENTICATION_BACKENDS in settings.py.
ModelBackend is a default authentication backend that has been provided by Django, and if you are using it, it checks if user is acive or not. It's sth like this:
def user_can_authenticate(self, user):
"""
Reject users with is_active=False. Custom user models that don't have
that attribute are allowed.
"""
is_active = getattr(user, 'is_active', None)
return is_active or is_active is None
I've made a user model with USERNAME_FIELD defined as phone_number. So login form requires phone_number and password. I want users to be able to also login through their emails. So I created an authentication backend class. Users can login with their phone numbers but they canbot do so with their emails and will receive the 'Username and/or password is wrong' message.
authentication.py:
from django.contrib.auth import get_user_model
class CustomAuthBackend:
def authenticate(self, username=None, password=None):
try:
user = get_user_model().objects.get(email=username)
if password:
if user.check_password(password):
return user
return None
except:
return None
def get_user(self, user_id):
try:
user = get_user_model().objects.get(pk=user_id)
return user
except:
return None
forms.py:
class UserLoginForm(forms.Form):
username = forms.CharField(label="Phone Number / Email")
password = forms.CharField(widget=forms.PasswordInput(), label="Password")
views.py:
class UserLogin(View):
form_class = UserLoginForm
template_name = "accounts/login.html"
def get(self, request):
return render(request, self.template_name, {"form": self.form_class})
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(
request, username=cd["username"], password=cd["password"]
)
if user:
login(request, user)
messages.success(request, "Logged in successfully.", "success")
return redirect("home:home")
else:
messages.error(request, "Username and/or password is wrong.", "danger")
return render(request, self.template_name, {"form": form})
messages.error(request, "Login failed", "danger")
return render(request, self.template_name, {"form": form})
settings.py:
AUTHENTICATION_BACKENDS = [
"django.contrib.auth.backends.ModelBackend",
"accounts.authentication.CustomAuthBackend",
]
Assuming that you have already included the custom backend in AUTHENTICATION_BACKENDS setting in settings.py file.
You can make a condition check that whether it is a phone no. or email using regex so:
import re
from django.contrib.auth import get_user_model
class CustomAuthBackend:
def authenticate(self, request, username=None, password=None):
UserModel = get_user_model()
# Check whether username is an email address or phone number
if re.match(r'^\+?\d{10,14}$', username):
try:
user = UserModel.objects.get(phone_number=username)
if user.check_password(password):
return user
except UserModel.DoesNotExist:
return None
else:
try:
user = UserModel.objects.get(email=username)
if user.check_password(password):
return user
except UserModel.DoesNotExist:
return None
def get_user(self, user_id):
try:
return get_user_model().objects.get(pk=user_id)
except get_user_model().DoesNotExist:
return None
I had forgotten to include request as a parameter in authenticate method. :)
Correct version:
def authenticate(self, request, username=None, password=None):
# ...
I am create a application where admin and customer login same browser.
I read many blog not able not fix my problem. As Django use session based login.
I am facing issue while logout my admin then my customer automatic logout. maybe session based functionally
My admin LoginView and Logoutview:
class AdminLoginView(SuccessMessageMixin,LoginView):
authentication_form = LoginForm
template_name = 'login.html'
redirect_field_name = reverse_lazy('admin_panel:dashboard')
redirect_authenticated_user = False
success_message = '%(username)s login Successfully !'
def dispatch(self, *args, **kwargs):
if self.request.user.is_authenticated:
# messages.info(self.request, f"{self.request.user.firstname} is already Logged In")
return redirect('/admin/dashboard/')
return super().dispatch(*args, **kwargs)
def get_success_url(self):
url = self.get_redirect_url()
LOGIN_REDIRECT_URL = reverse_lazy('admin_panel:dashboard')
return url or resolve_url(LOGIN_REDIRECT_URL)
class LogoutView(LogoutView):
"""
Log out the user and display the 'You are logged out' message.
"""
next_page = "/admin/login"
def dispatch(self, request, *args, **kwargs):
response = super().dispatch(request, *args, **kwargs)
messages.add_message(request, messages.INFO,'Successfully logged out.')
return response
I have implemented customer based login & logout
def LoginView(request):
form = LoginForm(request.POST or None)
if form.is_valid():
username = form.cleaned_data["username"]
password = form.cleaned_data["password"]
remember_me = form.cleaned_data["remember_me"]
user = User.objects.get(email=username)
if user and user.check_password(password):
if user.is_active:
if remember_me == False:
request.session.set_expiry(0)
request.session['user_id'] = user.id
request.session['username'] = user.email
return HttpResponseRedirect('/')
else:
context = {'auth_error': "You're account is disabled"}
return render(request, 'forntend-signin.html', context )
else:
context = {
'auth_error': 'username and password incorrect'
}
return render(request, 'forntend-signin.html', context)
else:
context = {
"form": form
}
return render(request, 'forntend-signin.html', context)
def customer_logout(request):
try:
if request.session['username']:
del request.session['user_id']
del request.session['username']
else:
del request.session['user_id']
except KeyError:
HttpResponseRedirect("/")
return HttpResponseRedirect("/")
Please suggest me how to fix this issue.
If there any documentation available the please share.
As the title explains, although I'm successfully logged in, I can't prevent the application from going back to the login page if I entered the path to the page in URL bar.
NOTE:I'm not using the built-in user or authentication classes.
Here is the code below:
class user_login_view(View):
form_class = LoginForm
template_name = 'main/login.html'
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
def post(self, request):
form = self.form_class(request.POST)
username = request.POST['username']
password = request.POST['password']
if form.is_valid:
try:
member = user.objects.filter(username=username).first()
except user.DoesNotExist:
member = None
if member != None and member and member.password == password:
request.session['username'] = username
return redirect('main:index')
else:
messages.error(request,'account does not exist')
return render(request, self.template_name,{'form': form})
else:
messages.error(request, 'account does not exist')
return render(request, self.template_name,{'form': form})
def index(request):
template_name = 'main/loggedin.html'
if request.session.has_key('username'):
username = request.session['username']
return render(request, template_name, {"username" : username})
else:
return HttpResponseRedirect(reverse('main:login'))
def logout(request):
try:
del request.session['username']
except:
pass
return HttpResponseRedirect(reverse('main:login'))
After creating a UserProfile model. I started to create login but I'm stuck because of get_user() error.
EXCEPTION
AttributeError: 'LoginForm' object has no attribute 'get_user'
Here are my codes:
UPDATE
class LoginView(FormView):
form_class = LoginForm
redirect_field_name = REDIRECT_FIELD_NAME
template_name = 'login.html'
success_url = '/'
def form_valid(self, form):
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(self.request, user)
return HttpResponseRedirect(self.get_success_url())
else:
return self.form_invalid()
def form_invalid(self):
return HttpResponseRedirect(reverse('accounts:login'))
def get_success_url(self):
if self.success_url:
redirect_to = self.success_url
else:
redirect_to = self.request.REQUEST.get(self.redirect_field_name, '')
netloc = urlparse.urlparse(redirect_to)[1]
if not redirect_to:
redirect_to = settings.LOGIN_REDIRECT_URL
elif netloc and netloc != self.request.get_host():
redirect_to = settings.LOGIN_REDIRECT_URL
return redirect_to
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid()
How to fix this? Any help would be appreciated. I'm really new on Django 1.5. Need help.
[update]
In the original code, the author is doing the authenticate stuff inside a form method called get_user. You are doing it outside the form already, so just replace form.get_user()with user.
I use a login view that is not class based, and I don't even care into using a Django form instance, but it should be easy to adapt:
def signin(request):
if request.method == 'POST':
user = authenticate(
email=request.POST.get('username', '').lower().strip(),
password= request.POST.get('password', ''),
)
if user is None:
messages.error(request, u'Invalid credentials')
else:
if user.is_active:
login(request, user)
return HttpResponseRedirect(request.GET.get('next', '/'))
else:
messages.error(request, u'User is not active.')
return render_to_response('login.html', locals(),
context_instance=RequestContext(request))
[old answer]
Define a get_user method for your form.
Untested (but should get you in the right path):
def get_user(self):
from django.contrib.auth import authenticate
return authenticate(
email=self.cleaned_data.get('username', '').lower().strip(),
password=self.cleaned_data.get('password', ''),
)