Pergunta

Como faço para autenticar AD usando Python + LDAP. Atualmente estou usando a biblioteca python-ldap e tudo o que está produzindo é lágrimas.

Eu não posso nem ligam para executar uma consulta simples:

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()

A execução deste com myusername@mydomain.co.uk password username me dá um dos dois erros:

Invalid Credentials -. Quando eu digitar errado ou intencionalmente usar credenciais erradas que não consegue autenticar

ldap.INVALID_CREDENTIALS: { 'info': '80090308: LdapErr: DSID-0C090334, comentário: erro AcceptSecurityContext, 52e dados, vece', 'desc': 'credenciais inválidas'}

ou

ldap.OPERATIONS_ERROR: { 'info': '00000000: LdapErr: DSID-0C090627, comentário:. Para realizar esta operação um ligamento bem sucedida deve ser concluída na conexão, dados 0, vece', 'desc': 'erro de Operações'}

O que estou perdendo para vincular adequadamente?

Estou recebendo os mesmos erros no fedora e janelas.

Foi útil?

Solução

Eu estava faltando

l.set_option(ldap.OPT_REFERRALS, 0)

A partir do inicialização.

Outras dicas

Se você está aberto a usando pywin32, você pode usar as chamadas Win32 de Python. Isso é o que fazemos no nosso servidor web CherryPy:

import win32security
token = win32security.LogonUser(
    username,
    domain,
    password,
    win32security.LOGON32_LOGON_NETWORK,
    win32security.LOGON32_PROVIDER_DEFAULT)
authenticated = bool(token)

Isso funcionou para mim, l.set_option (ldap.OPT_REFERRALS, 0) foi a chave para o acesso a ActiveDirectory. Além disso, eu acho que você deve adicionar um "con.unbind ()", a fim de fechar a conexão antes de terminar o script.

Aqui está um código simples que funciona para mim.

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")

Isto é baseado em um anterior resposta .

Se você tem Kerberos instalado e falar com AD, como seria o caso com, digamos, Centrify Express instalado e funcionando, você pode apenas usar python-Kerberos. Por exemplo.

import kerberos
kerberos.checkPassword('joe','pizza','krbtgt/x.pizza.com','X.PIZZA.COM')`

voltaria usuário uma verdadeira 'joe' tem senha 'pizza' no reino X.PIZZA.COM Kerberos. (Tipicamente, penso eu, o último seria o mesmo que o nome do domínio AD)

Eu vejo o seu comentário para @Johan Buret sobre o DN não fixação de seu problema, mas também acredito que é o que você deve olhar.

Dado o seu exemplo, o DN para a conta de administrador padrão no AD será: cn = administrador, cn = Users, dc = mydomain, dc = co, dc = uk - tente que

.

Eu tentei adicionar

l.set_option (ldap.OPT_REFERRALS, 0)

mas em vez de um erro Python só trava e não vai responder a mais nada. Talvez eu estou construindo o errado consulta de pesquisa, qual é a parte de base da procura? Estou usando o mesmo que o DN para a ligação simples (oh, e eu tinha que fazer l.simple_bind, em vez de 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)

Eu estou usando AD LDS ea instância é registrado para a conta corrente.

Eu tive o mesmo problema, mas foi sobre a codificação de senha

.encode('iso-8859-1')

Resolvido o problema.

Com base no excelente LDAP3 tutorial :

>>> 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

Eu fiz isso em Python3 mas é suposto ser compatível com Python 2.

Use um nome distinto para fazer login em seu system."CN=Your user,CN=Users,DC=b2t,DC=local" Ele deve funcionar em qualquer sistema LDAP, incluindo AD

Para me mudando de simple_bind_s() para bind() fez o truque.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top