I'm trying to integrate AD authentication into my application, but my company requires connections over TLS to AD to trust company CA signed certificates to complete the SSL/TLS handshake. How would I go about adding certificate validation to these settings?
# LDAP Connection Settings
LDAP_AUTH_URL = ['ldap://xxx.xxx.xxx.xx:636', 'ldap://xxx.xxx.xxx.xx:636']
# Initiate TLS on Connection
LDAP_AUTH_USE_TLS = True
LDAP_AUTH_TLS_VERSION = ssl.PROTOCOL_TLSv1_2
# LDAP Search BASE for Looking up Users
LDAP_AUTH_SEARCH_BASE = 'ou=users,ou=authentication,ou=security,dc=corp,dc=companycom,dc=com'
# The LDAP class that represents a user.
LDAP_AUTH_OBJECT_CLASS = 'user'
# User model fields mapped to the LDAP
# attributes that represent them.
LDAP_AUTH_USER_FIELDS = {
'username': 'SamAccountName',
'first_name': 'givenName',
'last_name': 'sn',
'email': 'EmailAddress',
'manager': 'manager',
'enabled': 'Enabled'
}
# A tuple of fields used to uniquely identify a user.
LDAP_AUTH_USER_LOOKUP_FIELDS = ('username')
# Path to a callable that takes a dict of {model_field_name: value},
# returning a dict of clean model data.
# Use this to customize how data loaded from LDAP is saved to the User model.
LDAP_AUTH_CLEAN_USER_DATA = "django_python3_ldap.utils.clean_user_data"
# Path to a callable that takes a user model, a dict of {ldap_field_name: [value]}
# a LDAP connection object (to allow further lookups), and saves any additional
# user relationships based on the LDAP data.
# Use this to customize how data loaded from LDAP is saved to User model relations.
# For customizing non-related User model fields, use LDAP_AUTH_CLEAN_USER_DATA.
LDAP_AUTH_SYNC_USER_RELATIONS = "django_python3_ldap.utils.sync_user_relations"
# Path to a callable that takes a dict of {ldap_field_name: value},
# returning a list of [ldap_search_filter]. The search filters will then be AND'd
# together when creating the final search filter.
LDAP_AUTH_FORMAT_SEARCH_FILTERS = "django_python3_ldap.utils.format_search_filters"
# Path to a callable that takes a dict of {model_field_name: value}, and returns
# a string of the username to bind to the LDAP server.
# Use this to support different types of LDAP server.
LDAP_AUTH_FORMAT_USERNAME = "django_python3_ldap.utils.format_username_openldap"
# Sets the login domain for Active Directory users.
LDAP_AUTH_ACTIVE_DIRECTORY_DOMAIN = 'corp'
# The LDAP username and password of a user for querying the LDAP database for user
# details. If None, then the authenticated user will be used for querying, and
# the `ldap_sync_users`, `ldap_clean_users` commands will perform an anonymous query.
LDAP_AUTH_CONNECTION_USERNAME = 'placeholder'
LDAP_AUTH_CONNECTION_PASSWORD = 'placeholder'
# Set connection/receive timeouts (in seconds) on the underlying `ldap3` library.
LDAP_AUTH_CONNECT_TIMEOUT = None
LDAP_AUTH_RECEIVE_TIMEOUT = None
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"handlers": {
"console": {
"class": "logging.StreamHandler",
},
},
"loggers": {
"django_python3_ldap": {
"handlers": ["console"],
"level": "INFO",
},
},
}
Again, I already have the CA bundle. I just need to trust it to be able to communicate with the AD server. Thanks for any ideas in advance!
Related
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'.
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
I want to create user through apache superset API if user already exist it should show message.
import requests
payload = { 'username': 'My user name',
'password': 'my Password',
'provider': 'db'
}
base_url="http://0.0.0.0:8088"
login_url =f"{base_url}/api/v1/security/login"
login_response =requests.post(login_url,json=payload)
access_token = login_response.json()
print(access_token)
# header
header = {"Authorization":f"Bearer {access_token.get('access_token')}"}
base_url="http://0.0.0.0:8088" # apache superset is running in my local system on port 8088
user_payload={
'first_name': "Cp",
'last_name': "user",
'username':"A",
'email': "user.#gmail.com",
'active': True,
'conf_password': "user#1",
'password': "user#1",
"roles":["Dashboard View"]
}
users_url = f"{base_url}/users/add"
user_response= requests.get(users_url, headers=header)
print(user_response)
print(user_response.text)
user_response = user_response.json()
print(user_response)
I tried to create user through mentioned API, some time it gives 200 success message, but after checking in apache superset website i can not see created user details.
If i am using the wrong API endpoint or wrong methods to create user please suggest me.
i wanted to insert new data into porstgresql using odooRPc i am having error like below
RPCError: dictionary update sequence element #0 has length 1; 2 is required
my python script code is :
def POST(self):
data = []
web.header('Access-Control-Allow-Origin', '*')
web.header('Access-Control-Allow-Credentials', 'true')
web.header('Content-Type', 'application/json')
auth = web.input()
print("auth")
print(auth)
name=auth['username']
pwd=auth['password']
city=auth['city']
eml=auth['eml']
mobile=auth['phone']
state_id=auth['state']
country_id=auth['country']
# print(type(auth['country']))
# country_id=auth.get('Country').get('id')
# country_id=auth['country'].get('id')
# print(country_id)
# state_id=auth['state']
# print(state_id)
odoo = odoorpc.ODOO('field.holisticbs.com',port=8069)
odoo.login('field.holisticbs.com','info#holisticbs.com','admin')
# Customer = odoo.execute_kw('res.partner','create',{'name':name,' email':eml,'mobile':mobile,' country_id':country_id,'state_id':state_id})
Customer = odoo.execute_kw('res.partner','create',{'name':name,' email':eml,'mobile':mobile})
print(Customer)
# Users = odoo.env['res.partner']
# user = Users.browse([int(idu)])
# print(user)
# Customer = odoo.execute_kw('res.user','create',{'login':eml,' password':pwd})
return json.dumps(Customer)
I have made my comments as below , kindly request you to find it as below it will help in your case:
Well there are many RPC Library (Python) for connecting with the API of Odoo/OpenERP:
xmlrpclib
odoorpc
erppeek
oerplib
openerplib..
In Your case You have chose the odoorpc.
Here is the code snippet for using it odoorpc:
import odoorpc
import json
domain ='localhost' #the domain
port=8069 #the active port
username = 'username' #the user name
password = 'password' #the user password
dbname = 'database_name' #the database
#Validate the credentials
odoo = odoorpc.ODOO(domain, port=port)
odoo.login(dbname, username, password)
#Login User details
user = odoo.env.user
print(user.name) # user name
print(user.company_id.name) # user company name
#Create a partner
user_data = odoo.execute('res.partner', 'create',
{'name':"PRAKASH",'
email':" prakashsharmacs24#gmail.com",
'mobile':"7859884833"})
print(user_data)
But i have also find you are using the method execute_kw so please use xmlrpclib if you want to use method execute_kw
Here is the code snippet for using it xmlrpclib:
import xmlrpclib
domain ='localhost' #the domain
port=8069 #the active port
username = 'username' #the user name
password = 'password' #the user password
dbname = 'database_name' #the database
#Validate the credentials
url='http://{domain}:{port}'.format(domain=domain,port=port)
login_url='{url}/xmlrpc/2/common'.format(url=url)
sock_common = xmlrpclib.ServerProxy(login_url)
uid = sock_common.login(dbname, username, password)
print sock_common.version()
print uid
models = xmlrpclib.ServerProxy('{}/xmlrpc/2/object'.format(url))
#Validate the access rights
print models.execute_kw(dbname, uid, password,
'res.partner', 'check_access_rights',
['read'], {'raise_exception': False})
#Execute the query
print models.execute_kw(dbname, uid, password,
'res.partner', 'search',
[[['is_company', '=', True], ['customer', '=', True]]])
You can also refer this Link for knowing the difference between the RPC library
I hope this will help you ..
I have set the SOCIAL_AUTH_LINKEDIN_FIELD_OAUTH2_SELECTORS field in my Django Settings per the instructions for LinkedIn configurations here: http://psa.matiasaguirre.net/docs/backends/linkedin.html
But when I run the authentication the additional email selector added to that setting is not added to the list of selectors in the backend call.
When I remove the field SOCIAL_AUTH_LINKEDIN_FIELD_OAUTH2_SELECTORS I get an error that it is missing:
'Settings' object has no attribute
'SOCIAL_AUTH_LINKEDIN_FIELD_OAUTH2_SELECTORS'
So I know I am using the correct settings name.
None of the added params make it to the backend though:
settings.SOCIAL_AUTH_LINKEDIN_FIELD_OAUTH2_SELECTORS = ['id',
'recommendations-received', 'positions', 'email-address', 'headline',
'industry', 'first-name', 'last-name', 'location', 'num-connections',
'skills']
I printed out the result of the backend and always just get the default selector list:
[edited backends/linkedin.py from
https://github.com/omab/python-social-auth/blob/master/social/backends/linkedin.py#L32]
def user_details_url(self):
# use set() since LinkedIn fails when values are duplicated
fields_selectors = list(set(['first-name', 'id', 'last-name'] +
self.setting('FIELD_SELECTORS', [])))
print fields_selectors
# user sort to ease the tests URL mocking
fields_selectors.sort()
fields_selectors = ','.join(fields_selectors)
return self.USER_DETAILS.format(fields_selectors)
#> ['first-name', 'id', 'last-name']
How can I add selectors through DJANGO Settings to expand the data returned when authenticating?
Aamir suggestion worked!:
SOCIAL_AUTH_LINKEDIN_OAUTH2_FIELD_SELECTORS
I ended up adding a print statement to social.strategies.django_strategies and got alisting of all the settings being pulled:
def get_setting(self, name):
print name
return getattr(settings, name)
Listing...
# SOCIAL_AUTH_REDIRECT_IS_HTTPS
# REDIRECT_IS_HTTPS
# SOCIAL_AUTH_LINKEDIN_OAUTH2_KEY
# SOCIAL_AUTH_LINKEDIN_OAUTH2_SECRET
# SOCIAL_AUTH_LINKEDIN_OAUTH2_REQUESTS_TIMEOUT
# SOCIAL_AUTH_REQUESTS_TIMEOUT
# REQUESTS_TIMEOUT
# SOCIAL_AUTH_LINKEDIN_OAUTH2_URLOPEN_TIMEOUT
# SOCIAL_AUTH_URLOPEN_TIMEOUT
# URLOPEN_TIMEOUT
# SOCIAL_AUTH_LINKEDIN_OAUTH2_FIELD_SELECTORS
....