3

編集: tl;dr - search_filterSEARCH で使用される引数が RFC4515 に準拠していない可能性があります。

Ubuntu 14.04 でバージョン 1.8.4 を実行している Django サーバーを使用しています。私は Python 3.4 を使用しており、そのためにldap3を使用して LDAP 認証を構成しようとしています。

これは、それぞれ 1.6.2、12.04、および 2.7.3 から上記のバージョンへのアップグレードの一部です。すべてが正常に機能していたので、問題は認証サーバーではなく、私の側にあると思います。

これが機能する方法は、以下に示すように、HTML フォームを介して渡されたユーザー名とパスワードを受け取る、authenticate_user.pyというファイルを取得したことです。

def authenticateStudent(request):
    username = request.POST.get('username','')
    logger.info("User " + username + " has logged in.")
    password = request.POST.get('password','')
    x = Auth(username, password)
    retVal = x.AuthenticatePy()
    logger.info('retVale is '+str(retVal)) #this returns False
    #more code and more logging

このメソッドは、Auth クラス (以下を参照) からオブジェクトをインスタンス化し、ユーザー名とパスワードを格納してから、そのクラスの AuthenticatePy() メソッドを呼び出します。

import logging
import sys
import os.path,subprocess
import ldap3 as ldap
from ldap3 import Connection, Server, SIMPLE, SYNC, SUBTREE, ALL


logger = logging.getLogger('Submission')

class Auth():

    studentName = ""
    studentEmail = ""
    studentMatrik = ""

    def __init__(self, username, password):
        self.username = username
        self.password = password

    def AuthenticatePy(self):
        user_dn = "cn="+self.username+",ou=users,ou=data,ou=prod,ou=authserver,dc=domain,dc=tld"
        base_dn = "dc=domain,dc=tld"
        server = Server("authserver.domain.tld", port=636, use_ssl=True)

        filter = "uid="+self.username #might be incorrect
        try:
            #if authentication successful, get the full user data
            connect = Connection(server, user=user_dn, password=self.password)
            connect.bind()
            logger.info('Connection Bind Complete!') #the last logged message from this method
            result = connect.search(search_base=base_dn, search_filter=filter, search_scope=SUBTREE)
            logger.info('SEARCHING COMPLETE') #does not appear in the log
            # return all user data results
            connect.unbind()
            uname = result[0][1]['cn'][0]
            studentName = result[0][1]['fullName'][0]
            studentEmail = result[0][1]['imHauptEMail'][0]
            studentMatrik = result[0][1]['imMatrikelNr'][0]
            logger.info('studentName is '+str(studentName))
            if uname == self.username :
                return studentName + '$' + studentEmail + '$' + studentMatrik
            else:
                return False
        except ldap.LDAPExceptionError:
            connect.unbind()
            return False

最後に表示されるログ メッセージは、「接続のバインドが完了しました!」です。何が壊れているのかよくわかりません。私が間違っていることは何か分かりますか?

編集:私はしばらくこれをトラブルシューティングしてきましたが、問題はsearch_filter検索関数を渡す引数にある可能性があると考え始めています。SEARCH 操作に関するldap3ドキュメントには、フィルター文字列は RFC4515 に準拠する必要があると記載されていますが、それを提供しているかどうかはわかりません。

4

2 に答える 2

9

私は ldap3 の作成者です。ldap フィルタは括弧内に含める必要があります。フィルタに先頭と末尾の括弧を追加してみてください:

filter = "(uid="+self.username + ")"

さようなら、ジョバンニ

于 2015-09-21T16:55:40.623 に答える
1

私はこの問題を解決することができました。引数の構文search_filterが実際に間違っていました。

他の回答で述べたように設定する必要がありました:
filter = "(uid="+self.username + ")"

ただし、どの属性を返したいかを示す必要もあったため、connect.search()の引数を変更する必要がありました。

connect.search(search_base=base_dn, search_filter=filter, search_scope=SUBTREE, attributes=['cn', 'fullName', 'imHauptEmail', 'imMatrikelNr'])

また、返された属性へのアクセスは、Python 2.7 のライブラリと同じようには機能せず、辞書のリストであるpython-ldapからアクセスできます。connect.response接続をアンバインドする前にこれらの属性にアクセスするconnect.unbind()必要があるため、属性から必要な値を格納するまで は移動されました。

uname = str(connect.response[0]['attributes']['cn'][0])
studentName = str(connect.response[0]['attributes']['fullName'][0])
studentEmail = str(connect.response[0]['attributes']['imHauptEMail'][0])
studentMatrik = str(connect.response[0]['attributes']['imMatrikelNr'][0])
connect.unbind()

実際には、これはすべてドキュメントで説明されています(下部の例のセクションを参照してください)。理解するのに数回読む必要がありました。

于 2015-09-23T13:03:19.113 に答える