Python + LDAP를 사용하여 Active Directory에 대한 인증
-
02-07-2019 - |
문제
Python + LDAP를 사용하여 AD에 대해 어떻게 인증합니까? 저는 현재 Python-LDAP 라이브러리를 사용하고 있으며 생산하는 것은 눈물입니다.
간단한 쿼리를 수행하기 위해 바인딩 할 수 없습니다.
import sys
import ldap
Server = "ldap://my-ldap-server"
DN, Secret, un = sys.argv[1:4]
Base = "dc=mydomain,dc=co,dc=uk"
Scope = ldap.SCOPE_SUBTREE
Filter = "(&(objectClass=user)(sAMAccountName="+un+"))"
Attrs = ["displayName"]
l = ldap.initialize(Server)
l.protocol_version = 3
print l.simple_bind_s(DN, Secret)
r = l.search(Base, Scope, Filter, Attrs)
Type,user = l.result(r,60)
Name,Attrs = user[0]
if hasattr(Attrs, 'has_key') and Attrs.has_key('displayName'):
displayName = Attrs['displayName'][0]
print displayName
sys.exit()
이것을 실행합니다 myusername@mydomain.co.uk password username
두 가지 오류 중 하나를 제공합니다.
Invalid Credentials
- 잘못 입력하거나 의도적으로 잘못된 자격 증명을 사용하면 인증하지 못합니다.
ldap.invalid_credentials : { 'info': '80090308 : ldaperr : dsid-0c090334, 댓글 : AccupteCurityContext 오류, 데이터 52E, Vece', 'desc': 'Invalid Credentials'}
또는
ldap.operations_error : { 'info': '00000000 : ldaperr : dsid-0c090627, 댓글 :이 작업을 수행하려면 연결에 성공적인 바인드가 완료되어야합니다. '}
제대로 묶기 위해 무엇을 놓치고 있습니까?
Fedora와 Windows에서 동일한 오류가 발생합니다.
해결책
나는 실종되었다
l.set_option(ldap.OPT_REFERRALS, 0)
초기에서.
다른 팁
pywin32를 사용하는 경우 Python에서 Win32 통화를 사용할 수 있습니다. 이것이 우리가 Cherrypy 웹 서버에서하는 일입니다.
import win32security
token = win32security.LogonUser(
username,
domain,
password,
win32security.LOGON32_LOGON_NETWORK,
win32security.LOGON32_PROVIDER_DEFAULT)
authenticated = bool(token)
그것은 나를 위해 일했고 l.set_option (ldap.opt_referrals, 0) Activedivedirectory에 액세스하는 열쇠였습니다. 또한 스크립트를 마치기 전에 연결을 닫기 위해 "Con.unbind ()"를 추가해야한다고 생각합니다.
다음은 저에게 적합한 간단한 코드입니다.
import ldap # run 'pip install python-ldap' to install ldap module.
conn = ldap.open("ldaphost.company.com")
conn.simple_bind_s("myuser@company.com", "mypassword")
이것은 a를 기반으로합니다 이전 답변.
Kerberos를 설치하고 광고와 대화하는 경우 Centrify Express 설치 및 실행의 경우와 같이 Python-Kerberos 만 사용할 수 있습니다. 예를 들어
import kerberos
kerberos.checkPassword('joe','pizza','krbtgt/x.pizza.com','X.PIZZA.COM')`
Kerberos Realm x.pizza.com에서 사용자 'Joe'가 암호 '피자'를 가지고 있습니다. (일반적으로, 후자는 광고 도메인의 이름과 동일 할 것이라고 생각합니다)
DN이 귀하의 문제를 해결하지 못한 것에 대해 @Johan Buret에 대한 귀하의 의견을 봅니다.
예를 들어, AD의 기본 관리자 계정의 DN은 다음과 같습니다.
나는 추가하려고했다
l.set_option (ldap.opt_referrals, 0)
그러나 오류 대신 파이썬은 매달려 더 이상 응답하지 않습니다. 어쩌면 검색 쿼리를 잘못 구축 할 수도 있습니다. 검색의 기본 부분은 무엇입니까? 나는 단순한 바인드를 위해 DN과 동일하게 사용하고 있습니다 (오, 그리고 나는해야했습니다. l.simple_bind
, 대신에 l.simple_bind_s
):
import ldap
local = ldap.initialize("ldap://127.0.0.1")
local.simple_bind("CN=staff,DC=mydomain,DC=com")
#my pc is not actually connected to this domain
result_id = local.search("CN=staff,DC=mydomain,DC=com", ldap.SCOPE_SUBTREE, "cn=foobar", None)
local.set_option(ldap.OPT_REFERRALS, 0)
result_type, result_data = local.result(result_id, 0)
AD LDS를 사용하고 있으며 인스턴스가 현재 계정에 등록되어 있습니다.
같은 문제가 있었지만 암호 인코딩에 관한 것이 었습니다.
.encode('iso-8859-1')
문제를 해결했습니다.
우수한 것을 기반으로합니다 LDAP3 튜토리얼:
>>> from ldap3 import Server, Connection, ALL, NTLM
>>> server = Server('server_name_or_ip', get_info=ALL)
>>> conn = Connection(server, user="user_name", password="password", auto_bind=True)
>>> conn.extend.standard.who_am_i()
>>> server.info
나는 위의 Python3에서 수행했지만 Python 2와 호환되어야합니다.
저명한 이름을 사용하여 시스템에 로그인하십시오."CN=Your user,CN=Users,DC=b2t,DC=local"
광고를 포함하여 모든 LDAP 시스템에서 작동해야합니다.
내가 바뀌는 것에 대해 simple_bind_s()
에게 bind()
트릭을했다.