代码之家  ›  专栏  ›  技术社区  ›  1729

使用python+ldap对活动目录进行身份验证

  •  99
  • 1729  · 技术社区  · 18 年前

    如何使用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:{“信息”:“80090308:LdapErr:DSID-0C090334,注释:AcceptSecurityContext错误,数据52e,vece”,“desc”:“无效凭据”}

    或

    ldap。操作错误:{'info':'00000000:LdapErr:DSID-0C090627,注释:为了执行此操作,必须在连接上成功完成绑定。,data 0,vece','desc':'操作错误'}

    我错过了什么才能正确绑定?

    我在fedora和windows上也遇到了同样的错误。

    11 回复  |  直到 13 年前
        1
  •  49
  •   1729    18 年前

    我失踪了

    l.set_option(ldap.OPT_REFERRALS, 0)
    

    从init。

        2
  •  30
  •   davidavr    18 年前

    如果你愿意使用pywin32,你可以使用Python的Win32调用。这就是我们在CherryPy web服务器中所做的:

    import win32security
    token = win32security.LogonUser(
        username,
        domain,
        password,
        win32security.LOGON32_LOGON_NETWORK,
        win32security.LOGON32_PROVIDER_DEFAULT)
    authenticated = bool(token)
    
        3
  •  7
  •   alfredocambera    17 年前

    这对我奏效了, l.set_option(ldap.OPT_REFERRALS,0) 是访问ActiveDirectory的关键。此外,我认为你应该添加一个“con.unbind()”,以便在完成脚本之前关闭连接。

        4
  •  5
  •   Community Mohan Dere    9 年前

    这里有一些对我来说很简单的代码。

    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 previous answer .

        5
  •  3
  •   codeape    14 年前

    基于优秀 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
    

    我在Python3中完成了上述操作,但它应该与Python 2兼容。

        6
  •  2
  •   Daniel Bungert    18 年前

    如果你安装了Kerberos并与AD通信,就像安装并运行Centrify Express一样,你可能只需要使用python Kerberos。例如

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

    如果用户“joe”在Kerberos域X.pizza中拥有密码“pizza”,则将返回True。通用域名格式。 (我认为,后者通常与AD域的名称相同)

        7
  •  2
  •   Nagev    7 年前

    我看到你对@Johan Buret关于DN没有解决你的问题的评论,但我也相信这是你应该调查的。

    举个例子,AD中默认管理员帐户的DN将是: cn=管理员,cn=用户,dc=mydomain,dc=co,dc=uk-请尝试一下。

        8
  •  1
  •   Andriy M    13 年前

    我试图添加

    l.set_option(ldap.OPT_REFERRALS,0)

    但Python只是挂起,不再响应任何事情,而不是出现错误。也许我构建的搜索查询有误,搜索的基础部分是什么?我使用与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,并且该实例已为当前帐户注册。

        9
  •  1
  •   Dr.Ü    10 年前

    我也遇到了同样的问题,但与密码编码有关

    .encode('iso-8859-1')
    

    解决了这个问题。

        10
  •  0
  •   Johan Buret    18 年前

    使用可分辨名称登录您的系统。 "CN=Your user,CN=Users,DC=b2t,DC=local" 它应该适用于任何LDAP系统,包括AD

        11
  •  0
  •   xcl    14 年前

    对我来说,从 simple_bind_s() 向 bind() 耍了花招。