Binding to Active Directory using django-auth-ldap - django

I'm trying to create user login authentication in my django app via Active Directory using django-auth-ldap. The problem is that I cannot bind to the AD using username (which is sAMAccountName LDAP equivalent). Part of my settings.py below:
import ldap
from django_auth_ldap.config import LDAPSearch
AUTHENTICATION_BACKENDS = [
'django_auth_ldap.backend.LDAPBackend',
]
AUTH_LDAP_START_TLS = False
AUTH_LDAP_ALWAYS_UPDATE_USER = False
AUTH_LDAP_SERVER_URI = 'ldap://ip_address:389'
AUTH_LDAP_BIND_DN = ''
AUTH_LDAP_BIND_PASSWORD = ''
AUTH_LDAP_USER_SEARCH = LDAPSearch('DC=example,DC=com', ldap.SCOPE_SUBTREE, '(sAMAccountName=%(user)s)')
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_REFERRALS: 0,
}
Console log:
ERROR search_s('DC=example,DC=com', 2, '(sAMAccountName=user)') raised OPERATIONS_ERROR({'desc': 'Operations error', 'info': '00000000: LdapErr: DSID-0C090627, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, vece'})
DEBUG search_s('DC=example,DC=com', 2, '(sAMAccountName=%(user)s)') returned 0 objects:
DEBUG Authentication failed for user: failed to map the username to a DN.
Any idea why this is not working?

Anonymous read access is not enabled by default. To perform the search operation, populate AUTH_LDAP_BIND_DN and AUTH_LDAP_BIND_PASSWORD with a valid account. I generally create dedicated "system" accounts (i.e. not a real person's account because your authentication starts failing every time the user changes their password).

Related

I want to integrate LDAP authentication in Django, but missing some configuration I guess

I want to integrate LDAP authentication in Django, but even authentication is not happening i.e even after providing the correct LDAP credentials the user details in the Django admin panel the user details are not getting stored in the Django user model.
Here's my setttings.py file in Django
AUTH_LDAP_SERVER_URI = 'ldaps://xxxxxx:636'
AUTH_LDAP_BIND_DN = 'CN=xxxxx,OU=Service,OU=Accounts,OU=SF_SAP,DC=sf,DC=priv'
AUTH_LDAP_BIND_PASSWORD = 'xxxxxxxx'
AUTH_LDAP_USER_SEARCH = LDAPSearch('OU=User,OU=Accounts,OU=SF_SAP, DC=sf,DC=priv',ldap.SCOPE_SUBTREE, '(CN=%(user)s)')
AUTH_LDAP_USER_ATTR_MAP = {
"first_name": "givenName",
"last_name": "sn",
"email": "mail",
"username": "uid",
"password": "userPassword",
}
AUTH_LDAP_PROFILE_ATTR_MAP = {
"home_directory": "homeDirectory"
}
AUTH_LDAP_ALWAYS_UPDATE_USER = True
AUTH_LDAP_CACHE_TIMEOUT = 3600
AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend',
'django.contrib.auth.backends.ModelBackend',
)
I enabled logging for LDAP and I see the following error in the logs
Binding as CN=xxxxxxxxx,OU=Service,OU=Accounts,OU=SF_SAP,DC=sf,DC=priv
Caught LDAPError while authenticating xxxxxx: SERVER_DOWN({'result': -1, 'desc': "Can't contact LDAP server", 'ctrls': [], 'info': 'error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed (unable to get local issuer certificate)'})
Question: Where does django look for the trusted certificates?
It would appear that the search filter is wrong : according to the user attribute map, username maps to uid, if it's correct the search filter should be '(uid=%(user)s)' :
AUTH_LDAP_USER_SEARCH = LDAPSearch(
'OU=User,OU=Accounts,OU=SF_SAP, DC=sf,DC=priv', ldap.SCOPE_SUBTREE, '(uid=%(user)s)'
)
But it could be the contrary (hard to know without a user dn example) : if the authentication works but user provisioning doesn't, then fix the mapping : "username": "cn".
You might also want to double check that all users you are trying to authenticate belong to the specified subtree 'OU=User,OU=Accounts,OU=SF_SAP, DC=sf,DC=priv'.

How do I refresh the Google access token with Django allauth?

The access token for google typically lasts 1 hour. How do I refresh the token without having the user login again?
github code for project: https://github.com/theptrk/learn_gcal
django-allauth Google login is set up the normal way with an added scope
THIRD_PARTY_APPS = [
# ...
"allauth.socialaccount",
"allauth.socialaccount.providers.google",
# This allows you to assign a site to a "social application"
SITE_ID = 1
SOCIALACCOUNT_PROVIDERS = {
"google": {
"SCOPE": [
# minimum scopes
"profile",
"email",
# additional scopes
"https://www.googleapis.com/auth/calendar.readonly",
],
"AUTH_PARAMS": {
"access_type": "offline",
},
}
}
# https://django-allauth.readthedocs.io/en/latest/configuration.html
# Use this for additional scopes: This defaults to false
SOCIALACCOUNT_STORE_TOKENS = True
Creating the credentials is different than the docs since the docs use a "secrets file" instead of getting tokens from the db
# get user and client credentials
token = SocialToken.objects.get(
account__user=request.user, account__provider="google"
)
client_id = env("GOOGLE_CLIENT_ID", default="")
client_secret = env("GOOGLE_CLIENT_SECRET", default="")
# create Credentials object
from google.oauth2.credentials import Credentials
creds=Credentials(
token=token.token,
refresh_token=token.token_secret,
token_uri="https://oauth2.googleapis.com/token",
client_id=client_id,
client_secret=client_secret,
)
Trying to retrieve events is totally fine if the access token is not expired
# retrieve google calendar events
from googleapiclient.discovery import build
from datetime import datetime
service = build("calendar", "v3", credentials=creds)
try:
events_result = (
service.events()
.list(
calendarId="primary",
timeMin=datetime.now().date().isoformat() + "Z",
maxResults=30,
singleEvents=True,
orderBy="startTime",
)
.execute()
)
except Exception as e:
print("Google API Error")
if e.status_code == 403:
if e.reason == "Request had insufficient authentication scopes.":
print("user needs to grant calendar scopes")
print("Token is likely expired at this point")
# I've tried:
# creds.refresh(...) but it hasnt worked

How to login using LDAP in Django

I am trying to enable LDAP server for login and authenticate in my Django application. I read django-auth-ldap tutorial and done all the changes in settings.py.
But I not able to login from LDAP server users, Django always try to login only form local database.
What i have to do and change any thing while login user? any changes is required in view.py authenticate() function for login.
My code snippets are below :
settings.py
AUTH_LDAP_SERVER_URI = 'ldap://my_domain.com'
AUTH_LDAP_BIND_DN = 'cn=admin,dc=my_domain,dc=com'
AUTH_LDAP_BIND_PASSWORD = 'My_password'
AUTH_LDAP_USER_SEARCH = LDAPSearch(
'ou=users,dc=my_domain,dc=com',
ldap.SCOPE_SUBTREE,
'(uid=%(user)s)',
)
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_REFERRALS: 0
}
# Set up the basic group parameters.
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
'ou=django,dc=my_domain,dc=com',
ldap.SCOPE_SUBTREE,
'(objectClass=groupOfNames)',
)
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType(name_attr='cn')
# Simple group restrictions
AUTH_LDAP_REQUIRE_GROUP = 'cn=enabled,ou=django,ou=groups,dc=my_domain,dc=com'
AUTH_LDAP_DENY_GROUP = 'cn=disabled,ou=django,ou=groups,dc=my_domain,dc=com'
# Populate the Django user from the LDAP directory.
AUTH_LDAP_USER_ATTR_MAP = {
"username": "uid",
"passsword": "userPassword"
}
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
'is_active': 'cn=active,ou=django,ou=groups,dc=my_domain,dc=com',
'is_staff': 'cn=staff,ou=django,ou=groups,dc=my_domain,dc=com',
'is_superuser': 'cn=superuser,ou=django,ou=groups,dc=my_domain,dc=com',
}
# This is the default, but I like to be explicit.
AUTH_LDAP_ALWAYS_UPDATE_USER = True
# Use LDAP group membership to calculate group permissions.
AUTH_LDAP_FIND_GROUP_PERMS = True
# Cache distinguised names and group memberships for an hour to minimize
# LDAP traffic.
AUTH_LDAP_CACHE_TIMEOUT = 3600
# Keep ModelBackend around for per-user permissions and maybe a local
# superuser.
AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend',
'django.contrib.auth.backends.ModelBackend',
)
#view.py
from django.contrib.auth import authenticate, login
def user_login(request):
user = authenticate(username = username, password = password)
login(request, user)
return HttpResponseRedirect('/')
Any code changes required in user_login() function or djagno automatically checks and authenticate users from LDAP as well as local database.
I am not sure which Django function will used for login purpose.
Any one please help me.
I was struggling for this soo long. and finally its working
with django-auth-ldap on Django 2.2 + Python 3.6.8 .
This is my settings.py
and its working fine.
import ldap
from django_auth_ldap.config import LDAPSearch, LDAPGroupQuery,GroupOfNamesType
AUTH_LDAP_SERVER_URI = 'ldap://192.168.122.222'
AUTH_LDAP_BIND_DN = 'CN=Django Admin,CN=Users,DC=hqvfx,DC=com'
AUTH_LDAP_BIND_PASSWORD = 'MyPassword'
AUTH_LDAP_USER_SEARCH = LDAPSearch('OU=all,OU=LSA_Users,DC=hqvfx,DC=com',ldap.SCOPE_SUBTREE, '(sAMAccountName=%(user)s)')
AUTH_LDAP_GROUP_SEARCH = LDAPSearch('OU=HQ_Groups,DC=hqvfx,DC=com',ldap.SCOPE_SUBTREE, '(objectClass=top)')
AUTH_LDAP_GROUP_TYPE = GroupOfNamesType()
AUTH_LDAP_MIRROR_GROUPS = True
# Populate the Django user from the LDAP directory.
AUTH_LDAP_USER_ATTR_MAP = {
'username': 'sAMAccountName',
'first_name': 'displayName',
'last_name': 'sn',
'email': 'mail',
}
AUTH_LDAP_USER_FLAGS_BY_GROUP = {
'is_active': 'CN=all, OU=HQ_Groups, DC=hqvfx, DC=com',
'is_staff': 'CN=all, OU=HQ_Groups, DC=hqvfx, DC=com',
'is_superuser': 'CN=all, OU=HQ_Groups, DC=hqvfx, DC=com',
}
AUTH_LDAP_ALWAYS_UPDATE_USER = True
AUTH_LDAP_FIND_GROUP_PERMS = True
AUTH_LDAP_CACHE_TIMEOUT = 3600
AUTHENTICATION_BACKENDS = (
'django_auth_ldap.backend.LDAPBackend',
'django.contrib.auth.backends.ModelBackend',
)

Django Auth is not finding User Account in LDAP

Morning,
I´m implementing Django Auth Ldap in my proyect but it is not working. I checked ldap connection (by Django shell) and returns a search, so I guess python-ldap is working. I used the next:
import ldap
con = ldap.initialize("ldap://hostname")
con.simple_bind_s( "CN=MyName MySurname, CN=Users, DC=CompanyName, DC=local", "MyPassword" )
con.search_s( 'DC=CompanyName, DC=local', ldap.SCOPE_SUBTREE, '(objectclass=person)', ['sn'] )
When I try to authenticate an user by web (using Django-Auth-Ldap), authentication always returns None.
Settings. (LDAP Configuration).
AUTH_LDAP_SERVER_URI = "ldap://hostname"
AUTH_LDAP_BIND_DN = "CN=MyName MySurname, CN=Users, DC=CompanyName, DC=local"
AUTH_LDAP_BIND_PASSWORD = "MyPassword"
AUTH_LDAP_USER_SEARCH = LDAPSearch("CN=Users, DC=CompanyName, DC=local", ldap.SCOPE_SUBTREE, "(uid=%(user)s)")
AUTH_LDAP_CONNECTION_OPTIONS = {
ldap.OPT_REFERRALS: False
}
from django_auth_ldap.backend import LDAPBackend
View.
def Login(request):
usr = "MyUserName"
pwd = "MyPassword"
if request.method == 'POST':
ldap_backend = LDAPBackend()
user = ldap_backend.authenticate(usr, pwd)
print user
print usr, pwd
In my view, I´m passing to the ldap authentication my user and password which I used for login in the domain. Is that correct?
I got the value "CN=MyName MySurname, CN=Users, DC=CompanyName, DC=local" from a command in Directory Active server, kind of: dsquery user
This is the AD Schema:
What Am I Doing wrong?
Thanks guys.
EDITED: The problem is when I define the search throug uid, if I define it as AUTH_LDAP_USER_SEARCH = LDAPSearch("CN=Users, DC=CompanyName, DC=local", ldap.SCOPE_SUBTREE, "(CN=%(user)s)") is working (and, in the view, I must to pass as usr = "MyNameMySurname" instead). How can I Define the search through the username which I used for login it.
Finally... I must to use samAccountName instead of CN. I hope it help you all. Thanks guys.

How to get all files of all users using google drive API

I am a 'domain admin' for a google account and would like to:
Get all of the users in my domain and "for each" user, give another user read-access everyone's files . I can get each user, but right now I do not understand how to get each users documents.
#!/usr/bin/python
import gdata.docs
import gdata.docs.service
from gdata.apps import client
userNameAtGmailCom = 'domainAdmin#someplace.com'
password = 'mypassword'
personToShareWith = "someGuy#gmail.com"
domain = 'someplace.com'
def login(userNameAtGmailCom, password, personToShareWith, domain):
client = gdata.apps.client.AppsClient(domain=domain)
client.ssl = True
client.ClientLogin(email=userNameAtGmailCom, password=password, source='apps')
all_users = client.RetrieveAllUsers()
for user in all_users.entry:
user_name = user.login.user_name
print user_name
password = user.login.password
print password
clientDocs = gdata.docs.service.DocsService()
#password always returns 'none'
#therefore I've commented out the 'bad authentication'
#that would happen if the lines below ran
#clientDocs.ClientLogin(user_name, password)
#documents_feed = clientDocs.GetDocumentListFeed()
#for document_entry in documents_feed.entry:
#print document_entry.title.text
#scope = gdata.docs.Scope(value=personToShareWith, type='user')
#role = gdata.docs.Role(value='reader')
#acl_entry = gdata.docs.DocumentListAclEntry(scope=scope, role=role)
#created_acl_entry = client.Post(acl_entry, document_entry.GetAclLink().href, converter=gdata.docs.DocumentListAclEntryFromString)
login(userNameAtGmailCom, password, personToShareWith, domain)
You should use the Google Drive API and use service accounts to perform Google Apps domain-wide delegation of authority:
https://developers.google.com/drive/delegation