Attached is the old authentication-ldap.cfg that works.

the position_field defines the field from the LDAP server that defines a
users role. For example staff,student, contractor etc.

The groupMapping_field is a string of comma separated string pairs,
separated by colons. If the position_field is staff then the group in
DSpace becomes staffsubmit, if enrolled then studentsubmit.

Also the LDAPAuthenticate.java with the group feature added.



On Mon, 2013-07-29 at 11:21 +0200, helix84 wrote:
> On Mon, Jul 29, 2013 at 6:58 AM, Keir Vaughan-Taylor <[email protected]> wrote:
> > The routine is only executed when a user is an admin user or if the
> > config allows anonymous search.
> 
> Yes, that was the intention. If, however, the previous version allowed
> your use case (you can get you own information but no-one else's), it
> is a regression and we should fix it.
> 
> I thought get-your-own-information worked in the anonymous search
> scenario, but I have no way of actually testing that. Did you try not
> to specify search.user and set search.anonymous = true?
> 
> Could you send us your old authentication-ldap.cfg that used to work?
> 
> > LDAP servers mostly use a challenge
> > response system where information for a person is supplied from a netid
> > (user name) and a correct password. That is; you can get you own
> > information but no-one else's.
> 
> As a workaround / supported use case, you could set up search.user to
> be a new LDAP user with search access to all user's attributes (only
> those needed by DSpace).
> 
> 
> Regards,
> ~~helix84
> 
> Compulsory reading: DSpace Mailing List Etiquette
> https://wiki.duraspace.org/display/DSPACE/Mailing+List+Etiquette

-- 
#---------------------------------------------------------------#
#------------LDAP AUTHENTICATION CONFIGURATIONS-----------------#
#---------------------------------------------------------------#
# Configuration properties used by the LDAP Authentication      #
# plugin, when it is enabled.                                   #
#---------------------------------------------------------------#
#
# In order to enable LDAP Authentication, you must first ensure the
# 'org.dspace.authenticate.LDAPAuthentication' OR 
# 'org.dspace.authenticate.LDAPHierarchicalAuthentication'
# class is added to the list of enabled AuthenticationMethods in 
'authenticate.cfg'.  
# See 'authenticate.cfg' for more info.
#
# If LDAP is enabled, then new users will be able to register
# by entering their username and  password without being sent the
# registration token. If users do not have a username and password,
# then they  can still register and login with just their email address
# the same way they do now.
#
# For providing any special privileges to LDAP users,
# you will still need to extend the SiteAuthenticator class to
# automatically put people who have a netid into a special
# group.  You might also want to give certain email addresses
# special privileges. Refer to the DSpace documentation for more
# information about how to do this.
#
# It may be necessary to obtain the values of these settings from the
# LDAP server administrators as LDAP configuration will vary from server
# to server.

# This setting will enable or disable LDAP authentication in DSpace.
# With the setting off, users will be required to register and login with
# their email address.  With this setting on, users will be able to login
# and register with their LDAP user ids and passwords.
# This setting is only used by the JSPUI.
enable = true


##### LDAP AutoRegister Settings #####

# This will turn LDAP autoregistration on or off.  With this
# on, a new EPerson object will be created for any user who
# successfully authenticates against the LDAP server when they
# first login.  With this setting off, the user
# must first register to get an EPerson object by
# entering their ldap username and password and filling out
# the forms.
autoregister = true


# This is the url to the institution's ldap server. The /o=myu.edu
# may or may not be required depending on the LDAP server setup.
# A server may also require the ldaps:// protocol.
#provider_url = ldap://ldap.myu.edu/o=myu.edu
provider_url = ldap://ldap.library.usyd.edu.au

# This is the unique identifier field in the LDAP directory
# where the username is stored.
#id_field = uid
id_field = uid

# This is the object context used when authenticating the
# user.  It is appended to the id_field and username.
# For example uid=username,ou=people,o=myu.edu.  This must match
# the LDAP server configuration.
#object_context = ou=people,o=myu.edu
object_context = ou=people,dc=ucc,dc=usyd,dc=edu,dc=au

# This is the search context used when looking up a user's
# LDAP object to retrieve their data for autoregistering.
# With autoregister turned on, when a user authenticates
# without an EPerson object, a search on the LDAP directory to
# get their name and email address is initiated so that DSpace
# can create a EPerson object for them.  So after we have authenticated against
# uid=username,ou=people,o=byu.edu we now search in ou=people
# for filtering on [uid=username].  Often the
# search_context is the same as the object_context
# parameter.  But again this depends on each individual LDAP server
# configuration.
#search_context = ou=people
search_context = ou=people,dc=ucc,dc=usyd,dc=edu,dc=au

# This is the LDAP object field where the user's email address
# is stored.  "mail" is the default and the most common for
# LDAP servers.  If the mail field is not found the username
# will be used as the email address when creating the eperson
# object.
#email_field = mail
email_field = mail

# This is the LDAP object field where the user's last name is
# stored.  "sn" is the default and is the most common for LDAP
# servers.  If the field is not found the field will be left
# blank in the new eperson object.
#surname_field = sn
surname_field = sn

# This is the LDAP object field where the user's given names
# are stored.  This may not be used or set in all LDAP instances.
# If the field is not found the field will be left blank in the
# new eperson object.
#givenname_field = givenName
givenname_field = givenName

# This is the field where the user's phone number is stored in
# the LDAP directory.  If the field is not found the field
# will be left blank in the new eperson object.
#phone_field = telephoneNumber
phone_field = telephoneNumber

# Usyd Custom Field
position_field = usydPersonEntitlement

##### LDAP users group #####

# If required, a group name can be given here, and all users who log in
# to LDAP will automatically become members of this group. This is useful
# if you want a group made up of all internal authenticated users.

groupMapping_field = staff:staffsubmit,enrolled:studentsubmit

#login.specialgroup = group-name
login.specialgroup = staffsubmit


##### Hierarchical LDAP Settings #####

# If your users are spread out across a hierarchical tree on your
# LDAP server, you will need to use the following stackable authentication
# class:
#  plugin.sequence.org.dspace.authenticate.AuthenticationMethod = \
#        org.dspace.authenticate.LDAPHierarchicalAuthentication
#
# You can optionally specify the search scope. If anonymous access is not
# enabled on your LDAP server, you will need to specify the full DN and
# password of a user that is allowed to bind in order to search for the
# users.

# This is the search scope value for the LDAP search during
# autoregistering. This will depend on your LDAP server setup.
# This value must be one of the following integers corresponding
# to the following values:
# object scope : 0
# one level scope : 1
# subtree scope : 2
#search_scope = 2
search_scope = 2

# The full DN and password of a user allowed to connect to the LDAP server
# and search for the DN of the user trying to log in. If these are not 
specified,
# the initial bind will be performed anonymously.
#search.user = cn=admin,ou=people,o=myu.edu
#search.password = password

# If your LDAP server does not hold an email address for a user, you can use
# the following field to specify your email domain. This value is appended
# to the netid in order to make an email address. E.g. a netid of 'user' and
# netid_email_domain as '@example.com' would set the email of the user
# to be '[email protected]
#netid_email_domain = @example.com
/*
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 * 2012-06-26
 * http://www.dspace.org/license/

 */
package org.dspace.authenticate;

import java.sql.SQLException;
import java.util.Hashtable;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchResult;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.dspace.authorize.AuthorizeException;
import org.dspace.core.ConfigurationManager;
import org.dspace.core.Context;
import org.dspace.core.LogManager;
import org.dspace.eperson.EPerson;
import org.dspace.eperson.Group;

/**
 * Authentication module to authenticate against a flat LDAP tree where
 * all users are in the same unit.
 *
 * @author Larry Stone, Stuart Lewis, Keir Vaughan-taylor
 * @version $Revision: 6568 $
 */
public class LDAPAuthentication
    implements AuthenticationMethod {
    protected String ldapTGroup;

    /** log4j category */
    private static Logger log = Logger.getLogger(LDAPAuthentication.class);

    /**
     * Let a real auth method return true if it wants.
     */
    public boolean canSelfRegister(Context context,
                                   HttpServletRequest request,
                                   String username)
        throws SQLException
    {
        // XXX might also want to check that username exists in LDAP.

        return ConfigurationManager.getBooleanProperty("authentication-ldap", "autoregister");
    }

    /**
     *  Nothing here, initialization is done when auto-registering.
     */
    public void initEPerson(Context context, HttpServletRequest request,
            EPerson eperson)
        throws SQLException
    {
        // XXX should we try to initialize netid based on email addr,
        // XXX  for eperson created by some other method??
    }

    /**
     * Cannot change LDAP password through dspace, right?
     */
    public boolean allowSetPassword(Context context,
                                    HttpServletRequest request,
                                    String username)
        throws SQLException
    {
        // XXX is this right?
        return false;
    }

    /*
     * This is an explicit method.
     */
    public boolean isImplicit()
    {
        return false;
    }

    /*
     * Add authenticated users to the group defined in dspace.cfg by
     * the ldap.login.specialgroup key.
     */
    public int[] getSpecialGroups(Context context, HttpServletRequest request) {
		// Prevents anonymous users from being added to this group, and the second check
		// ensures they are LDAP users
		try
		{
			if (!context.getCurrentUser().getNetid().equals(""))
			{
                                //<keir>
                                //Assign user to group according to value placed in string variable ldapTGroup by SpeakerToLDAP class
                                ldapTGroup=ldapTGroup.replace(":","");
                                log.info(LogManager.getHeader(context, "TargetGroup  ", ldapTGroup));
                                //</keir>

				if ((ldapTGroup != null) && (!ldapTGroup.trim().equals(""))) {
					Group ldapGroup = Group.findByName(context, ldapTGroup);
                                        
					if (ldapGroup == null) {
						// The group isn't there.
						log.warn(LogManager.getHeader(context, "position_field",
						"Group defined in position_field does not exist"));
						return new int[0];
					} 
					else {
                                                log.info(LogManager.getHeader(context,
                                                          "TgroupName Selected", ldapTGroup));

                                                int[] gid=new int[] { ldapGroup.getID() };

                                                for(int i =0;i < gid.length;i++) {
                                                   log.info(LogManager.getHeader(context,
                                                             "User Group Id ", "" + gid[i]) );
                                                }
                                                
						return new int[] { ldapGroup.getID() };
					}
				}
                                else {
					String groupName = ConfigurationManager.getProperty("login.specialgroup");
                                	log.info(LogManager.getHeader(context, "SpecialGroup  ", groupName));
					if ((groupName != null) && (!groupName.trim().equals(""))) {
						Group ldapGroup = Group.findByName(context, groupName);
						if (ldapGroup == null) {
							// Group isn't there.
							log.warn(LogManager.getHeader(context,
								"ldap_specialgroup",
								"Group defined in login.specialgroup does not exist"));
							return new int[0];
						} 
						else {
                                                        log.info(LogManager.getHeader(context,
                                                                "groupName Selected", groupName));
							return new int[] { ldapGroup.getID() };
						}
					}
                                }
			}
		}
		catch (Exception npe) {
			// The user is not an LDAP user, so we don't need to worry about them
		}
		return new int[0];
    }
	
	/*
     * MIT policy on certs and groups, so always short-circuit.
     *
     * @return One of:
     *   SUCCESS, BAD_CREDENTIALS, CERT_REQUIRED, NO_SUCH_USER, BAD_ARGS
     */
    public int authenticate(Context context,
                            String netid,
                            String password,
                            String realm,
                            HttpServletRequest request)
        throws SQLException
    {
        log.info(LogManager.getHeader(context, "auth", "attempting trivial auth of user="+netid));

        // Skip out when no netid or password is given.
        if (netid == null || password == null)
        {
        	return BAD_ARGS;
        }

        // Locate the eperson
        EPerson eperson = null;
        try
        {
        		eperson = EPerson.findByNetid(context, netid.toLowerCase());
        }
        catch (SQLException e)
        {
        }
        
        SpeakerToLDAP ldap = new SpeakerToLDAP(log);

        // if they entered a netid that matches an eperson
        if (eperson != null)
        {
            // e-mail address corresponds to active account
            if (eperson.getRequireCertificate())
            {
                return CERT_REQUIRED;
            }
            else if (!eperson.canLogIn())
            {
                return BAD_ARGS;
            }

            if (ldap.ldapAuthenticate(netid, password, context))
            {
                eperson = EPerson.findByNetid(context, netid.toLowerCase());
                context.setCurrentUser(eperson);
                log.info(LogManager.getHeader(context, "authenticate", "type=ldap"));
                return SUCCESS;
            }
            else
            {
                   return BAD_CREDENTIALS;
            }
        }

        // the user does not already exist so try and authenticate them
        // with ldap and create an eperson for them
        else
        {
            if (ldap.ldapAuthenticate(netid, password, context))
            {
                // Register the new user automatically
                log.info(LogManager.getHeader(context,
                                "autoregister", "netid=" + netid));

                // If there is no email and the email  domain is set, add it to the netid
                String email = ldap.ldapEmail;
                if (((email == null) || ("".equals(email))) &&
                    (!"".equals(ConfigurationManager.getProperty("authentication-ldap", "netid_email_domain"))))
                {
                    email = netid + ConfigurationManager.getProperty("authentication-ldap", "netid_email_domain");
                }

                if ((email != null) && (!"".equals(email)))
                {
                    try
                    {
                        eperson = EPerson.findByEmail(context, email);
	                    if (eperson!=null)
	                    {
	                        log.info(LogManager.getHeader(context,
	                                "type=ldap-login", "type=ldap_but_already_email"));

	                        context.setIgnoreAuthorization(true);
	                        eperson.setNetid(netid.toLowerCase());
	                        eperson.update();
	                        context.commit();
	                        context.setIgnoreAuthorization(false);
	                        context.setCurrentUser(eperson);
	                        return SUCCESS;
	                    }
	                    else
	                    {
	                        if (canSelfRegister(context, request, netid))
	                        {
	                            // TEMPORARILY turn off authorisation
	                            try
	                            {
	                                context.setIgnoreAuthorization(true);
	                                eperson = EPerson.create(context);

                                        if ((email != null) && (!"".equals(email))) {
                                            eperson.setEmail(email);
                                        }

	                                if ((ldap.ldapGivenName!=null)&&(!ldap.ldapGivenName.equals(""))) eperson.setFirstName(ldap.ldapGivenName);
	                                if ((ldap.ldapSurname!=null)&&(!ldap.ldapSurname.equals(""))) eperson.setLastName(ldap.ldapSurname);
	                                if ((ldap.ldapPhone!=null)&&(!ldap.ldapPhone.equals(""))) eperson.setMetadata("phone", ldap.ldapPhone);

	                                eperson.setNetid(netid.toLowerCase());
	                                eperson.setCanLogIn(true);
	                                AuthenticationManager.initEPerson(context, request, eperson);
	                                eperson.update();
	                                context.commit();
					context.setCurrentUser(eperson);
				    }
	                            catch (AuthorizeException e)
	                            {
	                                return NO_SUCH_USER;
	                            }
	                            finally
	                            {
	                                context.setIgnoreAuthorization(false);
	                            }

	                            log.info(LogManager.getHeader(context, "authenticate",
	                                        "type=ldap-login, created ePerson"));
	                            return SUCCESS;
	                        }
	                        else
	                        {
	                            // No auto-registration for valid certs
	                            log.info(LogManager.getHeader(context,
	                                            "failed_login", "type=ldap_but_no_record"));
	                            return NO_SUCH_USER;
	                        }
	                    }
                    }
                    catch (AuthorizeException e)
                    {
                        eperson = null;
                    }
                    finally
                    {
                        context.setIgnoreAuthorization(false);
                    }
                }
            }
        }
        return BAD_ARGS;
    }

    /**
     * Internal class to manage LDAP query and results, mainly
     * because there are multiple values to return.
     */
    public class SpeakerToLDAP {

        private Logger log = null;

        /** ldap email result */
        protected String ldapEmail = null;

        /** ldap name result */
        protected String ldapGivenName = null;
        protected String ldapSurname = null;
        protected String ldapPhone = null;

	/** ldap position result */
	protected String ldapPosition = null;
	protected String ldapGroupMapping = null;

        SpeakerToLDAP(Logger thelog)
        {
            log = thelog;
        }

        /**
         * contact the ldap server and attempt to authenticate
         */
        protected boolean ldapAuthenticate(String netid, String password, Context context)
        {
            if (!password.equals(""))
            {
                String ldap_provider_url = ConfigurationManager.getProperty("authentication-ldap","provider_url");
                String ldap_id_field = ConfigurationManager.getProperty("authentication-ldap","id_field");
                String ldap_search_context = ConfigurationManager.getProperty("authentication-ldap","search_context");
                String ldap_object_context = ConfigurationManager.getProperty("authentication-ldap","object_context");

                // Set up environment for creating initial context
                Hashtable env = new Hashtable(11);
                env.put(javax.naming.Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
                env.put(javax.naming.Context.PROVIDER_URL, ldap_provider_url);

                // Authenticate
                env.put(javax.naming.Context.SECURITY_AUTHENTICATION, "simple");
                env.put(javax.naming.Context.SECURITY_PRINCIPAL, ldap_id_field+"="+netid+","+ldap_object_context);
                env.put(javax.naming.Context.SECURITY_CREDENTIALS, password);

                DirContext ctx = null;
                try
                {
                    // Create initial context
                    ctx = new InitialDirContext(env);

                    String ldap_email_field = ConfigurationManager.getProperty("authentication-ldap","email_field");
                    String ldap_givenname_field = ConfigurationManager.getProperty("authentication-ldap","givenname_field");
                    String ldap_surname_field = ConfigurationManager.getProperty("authentication-ldap","surname_field");
                    String ldap_phone_field = ConfigurationManager.getProperty("authentication-ldap","phone_field");
                    //<keir>
                    String ldap_position_field = ConfigurationManager.getProperty("authentication-ldap","position_field");
                    String ldap_groupMapping_field = ConfigurationManager.getProperty("authentication-ldap","groupMapping_field");
                    //</keir>


                    Attributes matchAttrs = new BasicAttributes(true);
                    matchAttrs.put(new BasicAttribute(ldap_id_field, netid));

                    String attlist[] = {ldap_email_field, ldap_givenname_field, ldap_surname_field, ldap_phone_field, ldap_position_field, ldap_groupMapping_field};

                    //<keir>
                    //DBG for (int i=0; i<attlist.length;i++)
                    //DBG    log.info(LogManager.getHeader(context, "attlist:",attlist[i]));
                    //</keir>
                    // look up attributes
                    try
                    {
                        log.info(LogManager.getHeader(context, "ldapSrchContxt:",ldap_search_context));
                        NamingEnumeration answer = ctx.search(ldap_search_context, matchAttrs, attlist);
                        while(answer.hasMore()) {
                            SearchResult sr = (SearchResult)answer.next();
                            Attributes atts = sr.getAttributes();
                            Attribute att;

                            if (attlist[0]!=null)
                            {
                                    att = atts.get(attlist[0]);
                                    if (att != null) ldapEmail = (String)att.get();
                                    //<keir>
                                    log.info(LogManager.getHeader(context,
                                        "ldap_Email", ldapEmail));
                                    //</keir>
                            }

                            if (attlist[1]!=null)
                            {
                                    att = atts.get(attlist[1]);
                                    if (att != null) ldapGivenName = (String)att.get();
                                    //<keir>
                                    log.info(LogManager.getHeader(context,
                                        "ldap_ldapGivenName", ldapGivenName));
                                    //</keir>
                            }

                            if (attlist[2]!=null)
                            {
                                    att = atts.get(attlist[2]);
                                    if (att != null) ldapSurname = (String)att.get();
                                    //<keir>
                                    log.info(LogManager.getHeader(context,
                                        "ldap_ldapSurname", ldapSurname));
                                    //</keir>
                            }

                            if (attlist[3]!=null)
                            {
                                    att = atts.get(attlist[3]);
                                    if (att != null) ldapPhone = (String)att.get();
                                    //<keir>
                                    log.info(LogManager.getHeader(context,
                                        "ldap_phone", ldapPhone));
                                    //</keir>
                            }
	
                            //<keir>
                            if (attlist[4]!=null)
                            {
                                    att = atts.get(attlist[4]);
                                    if (att != null) ldapPosition = (String)att.get();
                                    log.info(LogManager.getHeader(context,
                                        "ldap_ldapPosition", ldapPosition));
                            }

                            if (attlist[5]!=null)    {
                                   //If there is a mapping of the ldap entry to internal dspace entries
                                   // get the mapping and assign the group to put the user in to that mapping
                                   String [] piecePair;
                                   att = atts.get(attlist[5]);
                                   // split string on commas, each item in string array then to be split on colon
                                   String [] mapPieces= ldap_groupMapping_field.split(",");
                                   ldapTGroup="";
                                   for (int i=0; i<mapPieces.length; i++) {
                                         piecePair=mapPieces[i].split(":");
                                         if (piecePair[0].equals(ldapPosition))
                                               ldapTGroup=piecePair[1];
                                   }
                                   log.info(LogManager.getHeader(context,
                                        "att came up null, Group Mapping field is ", ldap_groupMapping_field));
                                   log.info(LogManager.getHeader(context,
                                          "Group assign AAA  ldap_ldapTGroup", ldapTGroup));
                            }
                            else {
                                   //ldapPosition unmapped ldap group to put user in
                                   if(ldapPosition == null) ldapTGroup = ldapPosition;
                                   log.info(LogManager.getHeader(context,
                                            "Group assign BBB ", ldapTGroup));
                            }
                        }
                    }
                    //</keir>
                    catch (NamingException e)
                    {
                        // if the lookup fails go ahead and create a new record for them because the authentication
                        // succeeded
                        log.warn(LogManager.getHeader(context,
                                        "ldap_attribute_lookup", "type=failed_search "+e));
                        return true;
                    }
                }
                catch (NamingException e)
                {
                    log.warn(LogManager.getHeader(context,
                                        "ldap_authentication", "type=failed_auth "+e));
                    return false;
                }
                finally
                {
                    // Close the context when we're done
                    try
                    {
                        if (ctx != null)
                            ctx.close();
                    }
                    catch (NamingException e)
                    {
                    }
                }
            }
            else
            {
                return false;
            }

            return true;
        }
    }

    /*
     * Returns URL to which to redirect to obtain credentials (either password
     * prompt or e.g. HTTPS port for client cert.); null means no redirect.
     *
     * @param context
     *  DSpace context, will be modified (ePerson set) upon success.
     *
     * @param request
     *  The HTTP request that started this operation, or null if not applicable.
     *
     * @param response
     *  The HTTP response from the servlet method.
     *
     * @return fully-qualified URL
     */
    public String loginPageURL(Context context,
                            HttpServletRequest request,
                            HttpServletResponse response)
    {
        return response.encodeRedirectURL(request.getContextPath() +
                                          "/ldap-login");
    }

    /**
     * Returns message key for title of the "login" page, to use
     * in a menu showing the choice of multiple login methods.
     *
     * @param context
     *  DSpace context, will be modified (ePerson set) upon success.
     *
     * @return Message key to look up in i18n message catalog.
     */
    public String loginPageTitle(Context context)
    {
        return "org.dspace.eperson.LDAPAuthentication.title";
    }
}
------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent 
caught up. So what steps can you take to put your SQL databases under 
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
DSpace-tech mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dspace-tech
List Etiquette: https://wiki.duraspace.org/display/DSPACE/Mailing+List+Etiquette

Reply via email to