Dies ist eine alte Version des Dokuments!
Motivation
Die python-Module „ldappas“ und „ldapadapter“ sind eine schlechte Wahl. Beide Pakete lassen sich nur schlecht in die grok-Umgebung integrieren. Beide Pakete müssen umständlich im Management-Interface konfiguriert werden. Besser ist es, gleich ein eigenes auth-utility bereitzustellen. Als Basis dient diese sehr gute Anleitung:
http://grok.zope.org/documentation/how-to/authentication-with-grok
der Code (grok-1.0)
es werden einige Konstanten in einer externen config-Datei vorrausgesetzt.
Das Utility muß in der app registriert werden:
<source lang=„python“> class MyApp(grok.Application, GlobalContainer):
.... # registrierung der ldapauth und der plugins,sessions grok.local_utility( PluggableAuthentication, provides=IAuthentication, setup=ldapauth.setup_authentication, ) ....
</source>
Konfigurationseinstellungen werden in einer Datei config.py gespeichert.
Datei ldapauth.py:
<source lang=„python“> import config import grok
def setup_authentication(pau):
"""Set up pluggable authentication utility.
Sets up an IAuthenticatorPlugin and ICredentialsPlugin (for the authentication mechanism) """ pau.credentialsPlugins = ['credentials'] pau.authenticatorPlugins = ['ldapusers'] pau.prefix = u'pau3.'
from zope.app.authentication.session import SessionCredentialsPlugin from zope.app.authentication.interfaces import ICredentialsPlugin
class MyCreds(grok.GlobalUtility, SessionCredentialsPlugin):
grok.provides(ICredentialsPlugin)
grok.name('credentials')
loginpagename = 'login'
loginfield = 'form.login'
passwordfield = 'form.password'
from zope.app.authentication.interfaces import IAuthenticatorPlugin
class UserAuthenticatorPlugin(grok.GlobalUtility):
grok.provides(IAuthenticatorPlugin)
grok.name('ldapusers')
def authenticateCredentials(self, credentials):
if not isinstance(credentials, dict):
return None
if not ('login' in credentials and 'password' in credentials):
return None
account = self.getAccount(credentials['login'].strip().lower())
if account is None:
return None
if not account.checkPassword(credentials['password']):
return None
return PrincipalInfo(id=account.name,
title=account.cn,
description=account.cn)
def principalInfo(self, id):
account = self.getAccount(id)
if account is None:
return None
return PrincipalInfo(id=account.name,
title=account.name,
description=account.name)
def getAccount(self, login):
# ... look up the account object and return it ...
return Account(login)
from zope.app.authentication.interfaces import IPrincipalInfo
class PrincipalInfo(object):
grok.implements(IPrincipalInfo)
def __init__(self, id, title, description):
self.id = id
self.title = title
self.description = description
self.credentialsPlugin = None
self.authenticatorPlugin = None
import ldap from zope import component from zope.app.authentication.interfaces import IPasswordManager
class Account(object):
""" erzeugt einen account und stellt eine methode
checkpassword bereit, um das passwort zu testen
todo: das passwort wird bei jedem seitenaufruf ueberprueft,
hier sollte irgendwas in der session gemerkt werden (user is
authenticated oder sowas)
"""
def __init__(self, name):
self.name = name
self.password = None
def checkPassword(self, password):
""" hier wird das passwort ueberprueft, kann gegen beliebige
auth-quellen gemacht werden
in diesem fall gegen ldap
"""
lconn=ldap.initialize('ldaps://'+config.LDAPSERVER)
if True:
lconn.simple_bind_s()
r=lconn.search_s(config.LDAPSEARCHBASE,
ldap.SCOPE_SUBTREE,
'(uid=%s)' % self.name,
['cn'])
if len(r)==1:
dn,atts=r[0]
try:
lconn.simple_bind_s(dn,password)
except:
return False
self.cn=atts['cn'][0].decode('utf8')
return True
else:
return False
</source>
