On 28.05.2013 15:38, Tibor Simko wrote:
Hi!
Some time ago I wrote this up for Samuele. Isn't it included in the
howto's yet? I'd have it as a mediawiki format for some markdowning or
whaterver.
Great, can you please resend it in any format you may have, I can
convert it to Trac. Seems it was not included yet.
Here you go. It's based on the EPFL sample that comes wiht
Invenio. HTH :)
----------------------------------------------------------------------
== Configuring LDAP Login ==
LDAP login is already supplied with Invenio via a sample configuration.
The configuration as such is stored within two python scripts, which
need to be adopted accordingly.
''Note:'' This procedure requires the module '''python-ldap''' to be
installed properly.
=== external_authentication_ldap.py ===
This is a sample file supplied with the Invenio distribution. It can be
used to build the local LDAP authentication. It is imperative to note
that the install procedure of Invenio will overwrite this file,
resulting in all changes to be lost. Therefore, it is advisable to
derive an own file to hold all changes.
As it also contains all local configuration variables it seems advisable
to copy this file to a new name specific for the installation at hand.
For this manual the following LDAP setup is assumed:
o=EPFL, c=CH
|
|
+--ou=groups
| |
| |
| +--- cn=xxx
| displayName= name of the group
| uniqueIdentifier= some local id for groups
|
|
|
+--ou=users
| |
| |
| +---uid= some local id for users (ex: grfavre)
| uniqueIdentifier= another local id (ex: 128933)
| [email protected]
| memberOf= id of a group
| memberOf= id of another group
|
+
The following variables need to be adopted:
CFG_EXTERNAL_AUTH_LDAP_SERVERS = ['ldap://scoldap.epfl.ch']
This variable holds the address of the local LDAP server.
CFG_EXTERNAL_AUTH_LDAP_CONTEXT = "o=EPFL,c=CH"
The structure of this has to be adopted to the local LDAP context. This
is sensitive to the ordering. Use the topmost entry point that allows
for all subsequent queries.
CFG_EXTERNAL_AUTH_LDAP_USER_UID = ["uid", "uniqueIdentifier", "mail"]
All fields listed here are searched as login ids. That is in this
example a user might log in by providing his mail address or his uidNumber.
CFG_EXTERNAL_AUTH_LDAP_MAIL_ENTRY = 'mail'
Defines which entry on the ldap system contains the email address.
CFG_EXTERNAL_AUTH_LDAP_GROUP_MEMBERSHIP = 'memberOf'
Defines which entry will hold the group memberships. Those groups are
added to invenio as external groups.
CFG_EXTERNAL_AUTH_LDAP_GROUP_UID = 'uniqueIdentifier'
Which field holds the group identifiers as numbers.
CFG_EXTERNAL_AUTH_LDAP_GROUP_NAME = 'displayName'
The field to resolve the group ids to nice names.
CFG_EXTERNAL_AUTH_LDAP_HIDDEN_GROUPS = ['EPFL-unit', 'users']
Define which groups on the LDAP server should be hidden, ie. not
generated within Invenio.
The code within ''external_authentication_ldap.py'' needs some adoptions
to the local environment. First of all, a nickname is generated from the
data provided by the LDAP-server. This is done in the
''_get_nickname()'' function and is based upon the ''mail'' entry.
def _get_nickname(connection):
users = connection.search_s(CFG_EXTERNAL_AUTH_LDAP_CONTEXT,
ldap.SCOPE_SUBTREE,
query)
# We pick the first result, as all the data we are interested
# in should be the same in all the entries.
if len(users):
user_dn, user_info = users [0]
else:
return None
emails = user_info[CFG_EXTERNAL_AUTH_LDAP_MAIL_ENTRY]
if len(emails):
email = emails[0]
else:
return False
#
# Here some adoptions are in order
#
(left_part, right_part) = email.split('@')
nickname = left_part.replace('.', ' ').title()
if right_part != 'epfl.ch':
nickname += ' - ' + right_part
return nickname
return self._ldap_try(_get_nickname)
The code above results in ''[email protected]'' to generate the
nickname ''john smith'' while ''[email protected]'' would get
''john smith - somewhere.org''.
Next, fetching of group memberships might need some adoptions. This is
especially necessary if the LDAP-Server in question does not hold real
group memberships. The function in question that needs adoption is
''_get_groups()'':
def _get_groups(connection):
users = connection.search_s(CFG_EXTERNAL_AUTH_LDAP_CONTEXT,
ldap.SCOPE_SUBTREE,
query_person)
if len(users):
user_dn, user_info = users [0]
else:
return {}
groups = {}
#
# The following relies on every account to have this
# entry! This might not be always the case.
#
group_ids = user_info[CFG_EXTERNAL_AUTH_LDAP_GROUP_MEMBERSHIP]
for group_id in group_ids:
query_group = '(%s=%s)' %
(CFG_EXTERNAL_AUTH_LDAP_GROUP_UID,
group_id)
ldap_group =
connection.search_s(CFG_EXTERNAL_AUTH_LDAP_CONTEXT,
ldap.SCOPE_SUBTREE,
query_group)
if len(ldap_group):
group_dn, group_infos = ldap_group[0]
group_name =
group_infos[CFG_EXTERNAL_AUTH_LDAP_GROUP_NAME][0]
if group_name in CFG_EXTERNAL_AUTH_LDAP_HIDDEN_GROUPS:
continue
groups[group_id] = group_name
return groups
return self._ldap_try(_get_groups)
No general guides can be given to adopt this function as it has to
model the setup of the LDAP server. However, it should be noted that
''groups'' should always get set as otherwise Invenio will rise an
error and tell the user that the LDAP-Server as such is down. A very
simplistic function that would work if the server does not supply real
group memberships would be:
def _get_groups(connection):
users = connection.search_s(CFG_EXTERNAL_AUTH_LDAP_CONTEXT,
ldap.SCOPE_SUBTREE,
query_person)
if len(users):
user_dn, user_info = users [0]
else:
return {}
groups = {}
# Add everyone to the group "OTHERS". Every user must have
at least
# one group membership!
groups["OTHERS"] = "OTHERS"
#
# If a department is specified on the LDAP-Server add the
user to a
# group named like the department.
if CFG_EXTERNAL_AUTH_LDAP_GROUP_MEMBERSHIP in user_info:
group_ids =
user_info[CFG_EXTERNAL_AUTH_LDAP_GROUP_MEMBERSHIP]
for group_id in group_ids:
groups[group_id] = group_id
return groups
return self._ldap_try(_get_groups)
It assumes that ''CFG_EXTERNAL_AUTH_LDAP_GROUP_MEMBERSHIP'' is itself
already a speaking name (e.g. the property ''department'') and this is
also used to generate local groups from. As first of all every user is
added to the group ''OTHERS'' it also assures that the function always
returns at least one group membership.
=== access_control_config.py ===
This file needs to add LDAP as authentication method. To this end one
has first to load the ''external_authentication_ldap.py'' mentioned in
the first step. This is done by adding
from invenio.external_authentication_ldap_OWN import ExternalAuthLDAP
to the header in case on called the derived file
''external_authentication_ldap_OWN.py''. Next, LDAP has to be enabled
a bit further down within the code. Searching for ''#
CFG_EXTERNAL_AUTHENTICATION'' gives a pointer to the right section and
a helpful comment. If the site is neither declared to be CERN nor
OpenAire, the ''else'' section is the place to go:
else:
CFG_EXTERNAL_AUTH_DEFAULT = 'LDAP'
CFG_EXTERNAL_AUTH_USING_SSO = False
CFG_EXTERNAL_AUTH_LOGOUT_SSO = None
CFG_EXTERNAL_AUTHENTICATION = {
"LDAP": ExternalAuthLDAP(),
"Local": None
}
## "Robot": ExternalAuthRobot(enforce_external_nicknames=True,
use_zlib=False),
## "ZRobot": ExternalAuthRobot(enforce_external_nicknames=True,
use_zlib=True)
Here one specifies all login methods that should be allowed for the
site. In the example above the two default methods for robots were
removed and LDAP was added. Note also that setting
''CFG_EXTERNAL_AUTH_DEFAULT'' to ''LDAP'' will result in LDAP being the
main authenticaion method. Listing also ''Local'' in
''CFG_EXTERNAL_AUTHENTICATION'' would also allow local accounts to be
added to the system. If only LDAP should be enabled, the ''Local'' line
is to be removed. Invenio will then show only a login box an no selector
for the method.
=== invenio-local.conf ===
Finally, one should think about the global config variable
''CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS'' to be set properly in
invenio-local.conf. Setting it to ''5'' might be the desirable. With
this setting only admins can register local accounts, users can not edit
email addresses, passwords or login method. In fact, authentication via
LDAP does not require the user to set a password in Invenio, she should
just set her password on the LDAP-server. For details see also the
documentation of ''CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS''
----------------------------------------------------------------------
--
Kind regards,
Alexander Wagner
Subject Specialist
Central Library
52425 Juelich
mail : [email protected]
phone: +49 2461 61-1586
Fax : +49 2461 61-6103
www.fz-juelich.de/zb/DE/zb-fi
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
Forschungszentrum Juelich GmbH
52425 Juelich
Sitz der Gesellschaft: Juelich
Eingetragen im Handelsregister des Amtsgerichts Dueren Nr. HR B 3498
Vorsitzender des Aufsichtsrats: MinDir Dr. Karl Eugen Huthmacher
Geschaeftsfuehrung: Prof. Dr. Achim Bachem (Vorsitzender),
Karsten Beneke (stellv. Vorsitzender), Prof. Dr.-Ing. Harald Bolt,
Prof. Dr. Sebastian M. Schmidt
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------