开发者

How can I do two-stage authentication to an Active Directory server in Python?

I'm running Python 2.6 on a FreeBSD machine, and I would like to do (and I don't know the correct term for this) two-stage authentication against an active directory.

Basically, the process to log in user 'myuserid' is:

  1. Bind to the AD LDAP server using a system account created for this purpose (call it DOMAIN\gatekeeper)
  2. Verify myuserid's password against the credentials stored in the AD for that user.

I have the following code, which looks a lot like the code in 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')

This last results in this error:

=> 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'}

Every tutorial I see seems to presuppose that I'm running on Windows, which is not the case. How do I do this from Unix?


Your in multiple troubles there:

  1. SIMPLE Auth without SSL is usually disable on AD (and even the SSL version is often off)
  2. SIMPLE Auth does not really specify the password encoding (usually utf-8 works though)
  3. SIMPLE Auth might bring troubles with referrals
  4. Your AD user probably has a different CN when its Gatekeeper\DOMAIN, typically its something like cn=Gatekeeper,dc=Users,dc=DOMAIN,dc=COMPANY,dc=TLD or so (the Gatekeeper name is from the sAMAccountName property, the cn might be totally unrelated...)

So typically you need to do at least these things to get it to work:

  • Make sure your AD accepts SIMPLE auth at all
  • Bind with your gatekeeper account and find the DN to the username in AD (typically by searching for something like sAMAccountName or userPrincipalName)
  • Try to BIND to the DN you found with the password the user provided
  • If the bind succeeds you can treat the user as authenticated...

But if your that far its not much more work to use PAM or Kerberos instead.


LDAP returning error 49 with the subcode of 525 is not a bad password, but rather a bad bind DN. 52e is bad credentials. Check that you have the correct DN of the gatekeeper user.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜