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
でこれを実行すると、次の2つのエラーのいずれかが表示されます。
無効なクレデンシャル
-間違ったクレデンシャルを誤って入力したり、意図的に使用すると、認証に失敗します。
ldap.INVALID_CREDENTIALS:{'info': '80090308:LdapErr:DSID-0C090334、comment:AcceptSecurityContext error、data 52e、vece'、 'desc': 'Invalid credentials'}
または
ldap.OPERATIONS_ERROR:{'info': '00000000:LdapErr:DSID-0C090627、comment:この操作を実行するには、接続で正常なバインドを完了する必要があります。データ0、vece'、 'desc': 「操作エラー」}
適切にバインドするために不足しているものは何ですか?
FedoraとWindowsで同じエラーが表示されます。
解決
行方不明でした
l.set_option(ldap.OPT_REFERRALS, 0)
initから。
他のヒント
pywin32を使用する場合は、PythonからWin32呼び出しを使用できます。これは、CherryPy Webサーバーで行うことです:
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)はActiveDirectoryにアクセスするためのキーでした。さらに、「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")
これは、以前の回答に基づいています。
KerberosをインストールしてADと通信している場合、たとえばCentrify Expressをインストールして実行している場合と同様に、python-kerberosを使用できます。例:
import kerberos
kerberos.checkPassword('joe','pizza','krbtgt/x.pizza.com','X.PIZZA.COM')`
ユーザー 'joe'のパスワード 'pizza'がKerberosレルムX.PIZZA.COMにある場合、Trueを返します。 (通常、後者はADドメインの名前と同じだと思います)
DNが問題を解決していないというコメントを@Johan Buretに見ますが、それもあなたが検討すべきだと思います。
例を挙げると、ADのデフォルトの管理者アカウントのDNは次のようになります。 cn = Administrator、cn = Users、dc = mydomain、dc = co、dc = uk-それを試してください。
追加しようとしました
l.set_option(ldap.OPT_REFERRALS、0)
しかし、エラーの代わりにPythonはハングし、それ以上何にも応答しません。検索クエリを間違って作成している可能性がありますが、検索の基本部分は何ですか?シンプルバインドのDNと同じものを使用しています(ああ、 l.simple_bind_s
ではなく l.simple_bind
を実行する必要がありました):
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"
ADを含むすべてのLDAPシステムで動作するはずです
私にとっては、 simple_bind_s()
から bind()
に変更することでうまくいきました。