【问题标题】:How can I do two-stage authentication to an Active Directory server in Python?如何在 Python 中对 Active Directory 服务器进行两阶段身份验证?
【发布时间】:2010-08-23 21:22:12
【问题描述】:

我在 FreeBSD 机器上运行 Python 2.6,我想针对活动目录执行(我不知道正确的术语)两阶段身份验证。

基本上,登录用户'myuserid'的流程是:

  1. 使用为此目的创建的系统帐户绑定到 AD LDAP 服务器(称为 DOMAIN\gatekeeper
  2. 根据存储在 AD 中为该用户存储的凭据验证 myuserid 的密码。

我有以下代码,看起来很像this question 中的代码。

l = ldap.initialize(Server)
l.protoco_version = 3
l.set_option(ldap.OPT_REFERRALS, 0)
l.simple_bind_s('cn=gatekeeper,dc=DOMAIN,dc=COMPANY,dc=TLD', 'gatekeeper_password')

最后一个导致这个错误:

=> LDAPError - INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 525, vece', 'desc': 'Invalid credentials'}
---------------------------------------------------------------------------
INVALID_CREDENTIALS                       Traceback (most recent call last)

/Users/crose/projects/ldap-auth/9163_saas/webservices/aws/model/aw_registry/<ipython console> in <module>()

/Users/crose/virtualenv/ldap-auth/lib/python2.6/site-packages/ldap/ldapobject.pyc in simple_bind_s(self, who, cred, serverctrls, clientctrls)
    205     """
    206     msgid = self.simple_bind(who,cred,serverctrls,clientctrls)
--> 207     return self.result(msgid,all=1,timeout=self.timeout)
    208 
    209   def bind(self,who,cred,method=ldap.AUTH_SIMPLE):

/Users/crose/virtualenv/ldap-auth/lib/python2.6/site-packages/ldap/ldapobject.pyc in result(self, msgid, all, timeout)
    420         polling (timeout = 0), in which case (None, None) is returned.
    421     """
--> 422     res_type,res_data,res_msgid = self.result2(msgid,all,timeout)
    423     return res_type,res_data
    424 

/Users/crose/virtualenv/ldap-auth/lib/python2.6/site-packages/ldap/ldapobject.pyc in result2(self, msgid, all, timeout)
    424 
    425   def result2(self,msgid=ldap.RES_ANY,all=1,timeout=None):
--> 426     res_type, res_data, res_msgid, srv_ctrls = self.result3(msgid,all,timeout)
    427     return res_type, res_data, res_msgid
    428  

/Users/crose/virtualenv/ldap-auth/lib/python2.6/site-packages/ldap/ldapobject.pyc in result3(self, msgid, all, timeout)
    430     if timeout is None:
    431       timeout = self.timeout
--> 432     ldap_result = self._ldap_call(self._l.result3,msgid,all,timeout)
    433     if ldap_result is None:
    434       rtype, rdata, rmsgid, decoded_serverctrls = (None,None,None,None)

/Users/crose/virtualenv/ldap-auth/lib/python2.6/site-packages/ldap/ldapobject.pyc in _ldap_call(self, func, *args, **kwargs)
     94     try:
     95       try:
---> 96         result = func(*args,**kwargs)
     97         if __debug__ and self._trace_level>=2:
     98           if func.__name__!="unbind_ext":

INVALID_CREDENTIALS: {'info': '80090308: LdapErr: DSID-0C090334, comment: AcceptSecurityContext error, data 525, vece', 'desc': 'Invalid credentials'}

我看到的每个教程似乎都假定我在 Windows 上运行,但事实并非如此。我如何在 Unix 上做到这一点?

【问题讨论】:

  • 我建议您改为使用 kerberos PAM 路线。如果这是用于 web 服务,我建议使用 apache + mod_kerb。然后,您可以在 Windows 域中使用协商的身份验证进行单点登录。这就是我在组织内实现基于 unix 的 Web 服务的方式。
  • Kerberos PAM 身份验证可以工作;也许您可以为此提供说明?然而,Apache + mod_kerb 在这里不起作用。

标签: python unix authentication active-directory ldap


【解决方案1】:

你有很多麻烦:

  1. 没有 SSL 的 SIMPLE Auth 通常在 AD 上被禁用(甚至 SSL 版本也经常被关闭)
  2. SIMPLE Auth 并未真正指定密码编码(但通常 utf-8 有效)
  3. 简单的身份验证可能会给推荐带来麻烦
  4. 您的 AD 用户在其 Gatekeeper\DOMAIN 时可能有不同的 CN,通常是 类似 cn=Gatekeeper,dc=Users,dc=DOMAIN,dc=COMPANY,dc=TLD 左右(Gatekeeper name 来自 sAMAccountName 属性,cn 可能完全不相关...)

所以通常你至少需要做这些事情才能让它工作:

  • 确保您的 AD 完全接受 SIMPLE 身份验证
  • 与您的网守帐户绑定并在 AD 中找到用户名的 DN (通常通过搜索 sAMAccountName 或 userPrincipalName 之类的内容)
  • 尝试使用用户提供的密码绑定到您找到的 DN
  • 如果绑定成功,您可以将用户视为已通过身份验证...

但是,如果您到目前为止,使用 PAM 或 Kerberos 并没有太多工作要做。

【讨论】:

    【解决方案2】:

    LDAP returning error 49 子码为 525 不是错误密码,而是错误的绑定 DN。 52e 是错误的凭据。检查您是否拥有正确的网守用户 DN。

    【讨论】:

      猜你喜欢
      • 2010-09-10
      • 1970-01-01
      • 1970-01-01
      • 2012-05-25
      • 2012-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多