Difference between revisions of "Integrating EPrints with LDAP"

From EPrints Documentation
Jump to: navigation, search
(Blanked the page)
Line 1: Line 1:
'''Note''': some things on this page are specific to EPrints2. EPrints3 comes with example code in <tt>archives/ARCHIVEID/cfg/cfg.d/user_login.pl</tt> that just needs to be uncommented (and maybe customised). See [[LDAP]] or [[LDAP_user_login.pl]] for examples.
You also do not ''have'' to create ldapuser, ldapeditor and ldapadmin, you may also use the plain variants if you plan on using ''only'' LDAP accounts.
==Install Prerequisites==
Install the <tt>Net::LDAP</tt> and <tt>IO::Socket::SSL</tt> modules.
==Determine LDAP Setup==
The first step is to get Perl talking to your LDAP server. Determine the following parameters:
* the LDAP server name
* if the server doesn't support anonymous binds, a distinguished name (e.g. <tt>OU=jsmith, OU=users, DC=somewhere, DC=edu</tt>) and password to bind with
* the base name of user accounts (e.g. <tt>OU=users, DC=somewhere, DC=edu</tt>)
* the name of the username field (e.g. <tt>samaccountname</tt>, <tt>cn</tt>)
The <tt>http://files.eprints.org/27/01/ldaplookup</tt> script should get you started. Add your LDAP parameters to the script.
When run with an username as its parameter, <tt>ldaplookup</tt> should dump all the information associated with that account:
$ ./ldaplookup jsmith
Using LDAP protocol version 3
              objectClass: top
                        cn: jsmith
                        sn: Smith
You will probably need to tweak the LDAP parameters to suit your setup. See <tt>perldoc Net::LDAP</tt>.
==Configure user authentication==
The EPrints configuration lets you specify any number of user types (the defaults are "user", "editor" and "admin") each of which can be authorised in a different way. Suppose we want to have user, editor and admin accounts that are authorised by our LDAP server (i.e. internal staff) and also user, editor and admin accounts that are local to EPrints and authorised in the usual way (i.e. external users).
==Create new user types==
In <tt>/opt/eprints2/archives/ARCHIVEID/cfg/metadata-types.xml</tt>, copy and paste the existing user, editor, and admin types and change their names to ldapuser, ldapeditor and ldapadmin:
<dataset name="user">
    <type name="ldapuser" >
        <field name="password" />
        <field name="username" staffonly="yes"/>
    <type name="ldapeditor" >
        <field name="password" />
        <field name="username" staffonly="yes"/>
    <type name="ldapadmin" >
        <field name="password" />
        <field name="usertype" staffonly="yes" />
    <type name="user" >
        <field name="password" />
        <field name="usertype" staffonly="yes"/>
    <type name="editor" >
        <field name="password" />
        <field name="usertype" staffonly="yes" />
    <type name="admin" >
        <field name="password" />
        <field name="username" staffonly="yes" />
==Define user citation styles==
Define citation styles for the new user types in <tt>/opt/eprints2/archives/ARCHIVEID/cfg/citations-en.xml</tt>:
Just copy and paste the citation types for user_user, user_editor and user_admin and rename them to user_ldapuser, user_ldapeditor and user_ldapadmin.
==Define user typenames==
Define typenames for the new user types in <tt>/opt/eprints2/archives/ARCHIVEID/cfg/phrases-en.xml</tt>:
Just copy and paste the phrases for user_typename_user, user_typename_editor and user_typename_admin and rename them to user_typename_ldapuser, user_typename_ldapeditor and user_typename_ldapadmin.
Then, adjust the three new phrases values, e.g., the phrase value for the user_typename_ldapuser could be changed from "User" to "LDAP User".
==Configure user authentication==
Now configure user authentication in <tt>/opt/eprints2/archives/ARCHIVEID/cfg/ArchiveConfig.pm</tt>:
my $LDAP = { handler => \&ldapauthen };
$c->{userauth} = {
    user => {
        auth  => $CRYPTED_DBI,
        priv  =>  [ "subscription", "set-password", "deposit", "change-email", "change-user" ] },
    editor => {
        auth  => $CRYPTED_DBI,
        priv  =>  [ "subscription", "set-password", "deposit", "change-email", "change-user",
                "view-status", "editor", "staff-view" ] },
    admin => {
        auth  => $CRYPTED_DBI,
        priv  =>  [ "subscription", "set-password", "deposit", "change-email", "change-user",
                "view-status", "editor", "staff-view",
                "edit-subject", "edit-user" ] },
    ldapuser => {
        auth  => $LDAP,
        priv  =>  [ "subscription", "set-password", "deposit",  "change-user","no_edit_own_record" ] },
    ldapeditor => {
        auth  => $LDAP,
        priv  =>  [ "subscription", "set-password", "deposit",  "change-user","no_edit_own_record",
                "view-status", "editor", "staff-view" ] },
    ldapadmin => {
        auth  => $LDAP,
        priv  =>  [ "subscription", "set-password", "deposit", "change-user",
                "view-status", "editor", "staff-view", "edit-user" ] },
Here, the default user, editor and admin user types are still authenticated using the usual <tt>$CRYPTED_DBI</tt> construct, whereas ldapuser, ldapeditor and ldapadmin are authenticated by the <tt>$LDAP</tt> construct that we defined.
==Define LDAP authentication function==
Add the <tt>ldapauthen</tt> function to the end of <tt>ArchiveConfig.pm</tt>, filling in your LDAP settings:
use Net::LDAP;
    eval "use Apache::Const ':common'" || eval "use Apache2::Const ':common'";
sub ldapauthen
    my ($r) = @_;
    my ($key, $val, $dbh);
    return OK unless $r->is_initial_req; # only the first internal request
    my($res, $passwd_sent) = $r->get_basic_auth_pw;
    return $res if $res; # e.g. HTTP_UNAUTHORIZED
    # get username
    my ($user_sent) = $r->user;
    my $ldap = Net::LDAP->new ( "ldap.host.name", version=>3 );
    $ldap->start_tls( sslversion=>'sslv2' );
    unless( $ldap )
        print STDERR "$@";
        return SERVER_ERROR;
    # If the distinguished name of the user is not
    # computable from the username, perform a lookup
    # to determine the distinguished name
    my $mesg = $ldap->bind;
    # If your LDAP server doesn't allow anonymous binds
    # supply the dn/password of a valid account here
    # (e.g. an 'eprints' account created specially for
    # this purpose)
    #my $dn = "";
    #my $pword = "";
    #my $mesg = $ldap->bind( $dn, password=>$pword );
    my $base = "ou=user, dc=somewhere, dc=edu";
    my $result = $ldap->search (
                base    => "$base",
                scope  => "sub",
                filter  => "cn=$user_sent",
                attrs  =>  ['DN'],
    my $entr = $result->pop_entry;
    unless( defined $entr )
        return AUTH_REQUIRED;
    # Bind with the distinguished name and password of the user
    # If the distinguished name of the user is computable, this
    # is the only step required
    my $mesg2 = $ldap->bind( $entr->dn, password=>$passwd_sent );
    if( $mesg2->code )
        return AUTH_REQUIRED;
    return OK;
==Reload configuration==
Restart the apache server to reload the new configuration.
==Import user accounts from LDAP==
The final step is to import existing user accounts from the LDAP server.
The <tt>http://files.eprints.org/27/02/update_users</tt> script should get you started. Copy it to the <tt>/opt/eprints2/bin</tt> directory and add your LDAP settings.
Set <tt>$forreal</tt> to 1 to make changes to the database.
* If you see a "Sizelimit exceeded" error, you may need to import users in smaller batches, for example a faculty/dept at a time.
* <tt>update_users</tt> should be scheduled regularly using <tt>cron</tt> to keep EPrints in sync with the LDAP server
* For EPrints3 you will need to update two lines below;
*: <tt>Line 3:</tt> use EPrints::DataObj::User; #use EPrints::User;
*: <tt>Line 77:</tt> $user = EPrints::DataObj::User::create($session,"ldapuser"); #$user = EPrints::User::create_user( $session, "ldapuser" );

Revision as of 10:15, 6 August 2010