Differences between revisions 32 and 33
Revision 32 as of 2007-06-11 23:43:23
Size: 8859
Editor: dwp
Comment:
Revision 33 as of 2007-06-12 00:01:18
Size: 8913
Comment:
Deletions are marked like this. Additions are marked like this.
Line 52: Line 52:
    (!) Just use import ldap ; ldap.TLS_AVAIL = 0

Authentication using LDAP

I (NickPhillips) really need Moin to authenticate users using LDAP.

The "pluggable" authentication in Moin 1.5 makes this reasonably easy, except for one minor point.

The way our LDAP auth needs to work is as follows:

  • Connect to LDAP server
  • Bind anonymously
  • Search for supplied username, make sure there's only one match
  • Re-bind using supplied username and password
  • If bind using supplied username and password is successful, user is authenticated.

Note: I removed some outdated code, please see the hg repo (or latest moin release) for the latest code. -- ThomasWaldmann DateTime(2006-12-23T02:51:11Z)

Improvements

First, I'd like to be caching the LDAP connection between requests. This could be especially useful when using mod_python. I'm new to Python and mod_python, but if they work similarly to mod_perl (which I am familiar with), then this shouldn't be too hard. The question is just "where do I want to store this damn LDAP object?"

Second, I really don't want users to end up having LDAP usernames as WikiNames. I need to come up with a way of translating one to the other, so that the LDAP username is never displayed on the wiki except in the login box. I'm not sure how the UserPreferences form should handle this.

  • Why you want 2 different names for the wiki user name and login name? note that the wiki name can be any name, there is not special reason to use WikiName, and of course it does not work for many languages which does not have capitals.

Because the login names we have are ugly and make it hard to see who is who. They're intended purely as a unique id for authentication, and I'd like to use a name that's intended as a human-readable name for places that it's intended it should be read by humans :) I don't mean that I want to force the use of caps, just that I want to be able to map from a name that's not intended for humans to one that is. And vice-versa. The mapping could be a simple case of applying some algorithm to the login to get the WikiName, or a further LDAP lookup, or a lookup in a flat file, or some arbitrary database...

It seems to me like this could easily be done "pluggably", by plugging in a module that's required to provide two functions -- one to translate a WikiName to a login name, and one the other way. In the default case, each would just return its argument.

  • As a short term solution you may want to put the loginname into name field and the cleartext name into aliasname field. alias is only there for cosmetical purpose and gets shown in a mouseover bubble on RecentChanges e.g.

That's what I'm doing. Except that I don't yet have a way of automatically setting the aliasname.

  • Please take a look in the Code of ldap-feature in the bugzilla software. There you can define which ldap field is used as bugzilla username and mail. It is also possible to make an authenticated ldap search. That is important for me and all other how want to bind moinmoin with Microsoft ActiveDirectory ldap, because MS ADS don't allow unauthenticated ldap searchs!

It wouldn't be too hard to allow an authenticated bind for the search, but I think you may confusing things when you talk about mail. This module is for authentication, and any other information lookups should be performed in a separate module -- what if I want to use LDAP for auth but MySQL for getting email address, aliasname etc.?

News 2006-12-22

I updated the ldap auth code in the 1.5 branch (see CHANGES for details). If you run a ldap setup, please help testing this and report about success/failure below.

  • I've installed 1.5.7 with ldap authentication. I've used the ldap configuration example and I've adapted it to my site. Some comments I have:
    • If ldap_start_tls is false, other configuration parameters (ldap_tls_cacertdir, ldap_tls_cacertfile ...) shouldn't be required and the code must be changed maybe this way: in line 365 instead of if ldap.TLS_AVAIL: it should be if starttls and ldap.TLS_AVAIL:

      • No. There are two methods requiring the certs: TLS and SSL. SSL needs them even if TLS is not being used.
        • Even if I set ldap_start_tls = 0, I get the following error: {{{[Mon Jun 11 16:40:04 2007] got name=ray5147 login=True logout=False

[Mon Jun 11 16:40:04 2007] LDAP: Setting misc. options... [Mon Jun 11 16:40:04 2007] LDAP: caught an exception, traceback follows... [Mon Jun 11 16:40:04 2007] Traceback (most recent call last):

  • File "/usr/lib/python2.3/site-packages/MoinMoin/auth.py", line 365, in ldap_login
    • if ldap.TLS_AVAIL:

AttributeError: 'module' object has no attribute 'TLS_AVAIL'}}}

  • I believe there should be an additional check done in the code.

    (!) Just use import ldap ; ldap.TLS_AVAIL = 0

  • If so, ¿does this mean we need to define ldap_tls_cacertdir, ldap_tls_cacertfile ..., even I we just need SSL access, and we use selfsigned certificates? Please, let me know which are the minimum options needed. ¿Could we accept any certificate even if we haven't got the corresponding CA certificate?
  • Maybe it is due to I have defined ldap_tls_cacertdir, ldap_tls_cacertfile ... as a void string, and I use the SSL method, but the first time I try to login everything goes well, but the second try generate a "segment violation" error. This is my log file
    [Tue Feb 20 13:01:54 2007] got name=None login=False logout=False
    [Tue Feb 20 13:02:00 2007] got name=miusuario login=True logout=False
    [Tue Feb 20 13:02:00 2007] LDAP: Setting misc. options...
    [Tue Feb 20 13:02:00 2007] LDAP: Trying to initialize ldaps://mihost.midominio.pri.
    [Tue Feb 20 13:02:00 2007] LDAP: Connected to LDAP server ldaps://mihost.midominio.pri.
    [Tue Feb 20 13:02:00 2007] LDAP: Bound with binddn
    [Tue Feb 20 13:02:00 2007] LDAP: Searching (uid=miusuario)
    [Tue Feb 20 13:02:00 2007] LDAP: dn:uid=miusuario,ou=people,dc=midominio,dc=pri
    [Tue Feb 20 13:02:00 2007] mail: ['miusuario@midominio.pri']
    [Tue Feb 20 13:02:00 2007] givenName: ['Mi Usuario']
    [Tue Feb 20 13:02:00 2007] displayName: ['Mi Usuario de trabajo']
    [Tue Feb 20 13:02:00 2007] sn: ['de trabajo']
    [Tue Feb 20 13:02:00 2007] LDAP: DN found is uid=miusuario,ou=people,dc=midominio,dc=pri, trying to bind with pw
    [Tue Feb 20 13:02:00 2007] LDAP: Bound with dn uid=miusuario,ou=people,dc=midominio,dc=pri (username: miusuario)
    [Tue Feb 20 13:02:00 2007] LDAP: creating userprefs with name misuario, email miusuario@midominio.pri alias Mi Usuario de trabajo
    [Tue Feb 20 13:02:02 2007] got name=None login=False logout=True
    [Tue Feb 20 13:02:03 2007] got name=None login=False logout=False
    [Tue Feb 20 13:02:13 2007] got name=miusuario login=True logout=False
    [Tue Feb 20 13:02:13 2007] LDAP: Setting misc. options...
    [Tue Feb 20 13:02:13 2007] LDAP: Trying to initialize ldaps://mihost.midominio.pri.
    [Tue Feb 20 13:02:13 2007] LDAP: Connected to LDAP server ldaps://mihost.midominio.pri.
    Then I get this error message on the console
    /etc/init.d/moin: line 1: 10985 Violación de segmento   /var/lib/moin/bin/moin.fcg >>/var/log/moin.log 2>&1
    And the moin.fcg has died. I'm using apache2 with fastcgi and moin.fcg is run as an external application. I've tried it several times with the same results. Without SSL (ldap://mihost.midominio.pri) everything goes well.
  • Python code doesn't do segmentation violations, this must be some C code (maybe some library problem?).
  • The SSL/TLS stuff isn't really tested. I didn't have segfaults, but all sorts of other weird error msgs and I couldn't tell if it was due to misconfigured server or misbehaved client. Someone with some "proven to work" ldaps or ldap/tls server needs to test it.
  • You only need to configure the tls stuff needed, the rest may stay at 0 or . The python-ldap stuff should be able to use server certs as well as client certs and I just added options for all.

  • The example should say that ldap_binddn and ldap_bindpw must be defined, and if you want anonymous bind, they must be a void string: ldap_binddn='' and ldap_bindpw=''

    • I added a sample for anon bind and a hint that they must be defined.
  • It seems that ldap authentication doesn't fallback to other authentication mechanism, at least, Moin can't recognize my local created users (they were created when ldap authentication was not activated). Could it be possible to control this behaviour with a cofigurable option? For example ldap_fallback_authentication = True.

    • The concrete use case for which ldap auth was implemented didn't want that fallback. But adding an option is a good idea for those who want it.

Test script

This can be used to debug ldap auth problems, especially if your LDAP/AD setup is rather complex:

inline:ldaptest.py


CategoryFeatureImplemented

MoinMoin: FeatureRequests/AuthLDAP (last edited 2008-10-22 13:58:17 by EricVeirasGalisson)