2016-06-07 4 views
2

Wir haben eine Pyramid-Anwendung, die LDAP für die Authentifizierung verwendet. Derzeit verwenden wir nicht pyramid_ldap, sondern benutzerdefinierten Code basierend auf python_ldap, um eine Verbindung zum LDAP-Server herzustellen.Erratic INSUFFICIENT_ACCESS Fehler bei der Verwendung von LDAP

Der Code ist in einer Singleton-Klasse: die __init__ Methode (genauer: das Verfahren während der Exemplarerstellung genannt) ruft ldap.initialize die LDAPObject und simple_bind_s zu erstellen. Hier ist der Code (der Benutzer kann durch die LDAP-Server übergibt durch ein lokales Administrator-Konto bereitstellt):

class Singleton(object): 
    ''' 
    Implements the singleton pattern. A class deriving from ``Singleton`` can 
    have only one instance. The first instanciation will create an object and 
    other instanciations return the same object. Note that the :py:meth:`__init__` 
    method (if any) is still called at each instanciation (on the same object). 
    Therefore, :py:class:`Singleton` derived classes should define 
    :py:meth:`__singleton_init__` 
    instead of :py:meth:`__init__` because the former is only called once. 
    ''' 
    @classmethod 
    def get_instance(cls): 
     try: 
      return getattr(cls, '_singleton_instance') 
     except AttributeError: 
      msg = "Class %s has not been initialized" % cls.__name__ 
      raise ValueError(msg) 

    def __new__(cls, *args, **kwargs): 
     if '_singleton_instance' not in cls.__dict__: 
      cls._singleton_instance = super(Singleton, cls).__new__(cls) 
      singleton_init = getattr(cls._singleton_instance, 
           '__singleton_init__', None) 
      if singleton_init is not None: 
       singleton_init(*args, **kwargs) 
     return cls._singleton_instance 

    def __init__(self, *args, **kwargs): 
     ''' 
     The __init__ method of :py:class:`Singleton` derived class should do nothing. 
     Derived classes must define :py:meth:`__singleton_init__` instead of __init__. 
     ''' 

    def __singleton_init__(self, *args, **kwargs): 
     super(Singleton, self).__init__(*args, **kwargs) 

class UsersAndGroups(Singleton): 
    """ 
    Class used to query the LDAP directory. 
    """ 
    def __singleton_init__(self, admin_login, admin_password, 
          server, ldap_admin_dn, ldap_password, users_dn, 
          groups_dn): 
     self.admin_login = admin_login 
     self.admin_password = admin_password 
     self.server = server 
     self.ldap_admin_dn = ldap_admin_dn 
     self.ldap_password = ldap_password 
     self.users_dn = users_dn 
     self.groups_dn = groups_dn 

     # Check 
     if admin_login and (not admin_password): 
      raise ValueError('You must specify a password for the local admin') 
     self.has_local_admin = (admin_login) and (admin_password) 
     if (not self.server) and (not self.has_local_admin): 
      raise ValueError(
       'You must specify an LDAP server or a local admin') 

     # Connect to LDAP server 
     if self.server: 
      self.ldap_connection = ldap.initialize(self.server) 
      self.ldap_connection.simple_bind_s(self.ldap_admin_dn, 
               self.ldap_password) 
     else: 
      self.ldap_connection = None 

Die Singleton in der Server-Start-Funktion erstellt wird (so vor jeder Anfrage) und die nachfolgenden Anfragen abrufen nur der Beispiel. Wir verwenden das admin Konto anmelden:

def main(global_config, **settings): 

    # Create routes and so on  
    # Get configuration for LDAP connection from app.registry.settings 

    # Create the singleton to connect to LDAP 
    app.users_groups = UsersAndGroups(admin_login, admin_password, ldap_server, 
             ldap_admin_dn, ldap_password, users_dn, 
             groups_dn) 

    return app 

Das meiste Zeit funktioniert, aber manchmal LDAP-Operationen nicht mit INSUFFICIENT_ACCESS Fehler. Der Fehler tritt auf, wenn wir den Server zum Beispiel bei lokaler Entwicklung neu starten (in diesem Fall verwenden wir pserve mit der Option reload), aber auch auf dem Produktionsserver (wo die Dienste verwaltet werden über circus und chaussette - wir starten normalerweise mehrere Prozesse) . Die einzige Lösung, die wir gefunden haben, besteht darin, den Server herunterzufahren und neu zu starten.

Wir suchen nach Hinweisen auf was passiert und wie man es löst.

Der Benutzername und das Passwort sind korrekt, da es die meiste Zeit funktioniert. AFAIU ein Problem in Bindung sollte eine Ausnahme beim Serverstart auslösen. Ich frage mich, ob das Autoreload oder die mehreren Prozesse solche Probleme auslösen könnten (da es normalerweise beim Neustart des Servers funktioniert).

Einige Versionsinformationen:

  • OS: Ubuntu 12.04 oder 14.04
  • Python: 2.7
  • OpenLDAP: 2.4.28
  • python_ldap: 2.4.25
+1

Yeah. Sie müssen hier Code anzeigen. –

+0

Sie haben wahrscheinlich recht. Denkst du, ich sollte auch die 'Zirkus'-Konfiguration hinzufügen? Das Problem tritt auch während der lokalen Entwicklung ohne Zirkus auf. –

Antwort

0

Ich erkannte, dass der Fehler von woanders im Code kommt.