All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.wikitty.services.WikittyServiceAuthenticationLDAP Maven / Gradle / Ivy

The newest version!
/*
 * #%L
 * Wikitty :: api
 * %%
 * Copyright (C) 2012 CodeLutin, Benjamin Poussin
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as 
 * published by the Free Software Foundation, either version 3 of the 
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */
package org.nuiton.wikitty.services;

import java.util.Collections;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Properties;
import java.util.UUID;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuiton.config.ApplicationConfig;
import org.nuiton.util.TimeLog;
import org.nuiton.wikitty.WikittyConfigOption;
import org.nuiton.wikitty.WikittyService;
import org.nuiton.wikitty.entities.Wikitty;
import org.nuiton.wikitty.entities.WikittyImpl;
import org.nuiton.wikitty.entities.WikittyUser;
import org.nuiton.wikitty.entities.WikittyUserHelper;
import org.nuiton.wikitty.query.WikittyQuery;
import org.nuiton.wikitty.query.WikittyQueryMaker;

/**
 * Permet de faire une authentification sur un serveur LDAP. Il faut pour cela
 * fournir les informations pour se connecter au LDAP (url du serveur, pattern
 * des DN des utilisateurs et toutes autres informations utiles).
 *
 * Il est possible d'indiquer de creer automatiquement l'objet WikittyUser
 * associe au compte LDAP si celui-ci n'existe pas. Si le WikittyUser n'existe
 * pas et qu'on a pas le droit de le creer, l'authentification echoue forcement
 *
 * @author poussin
 * @version $Revision$
 *
 * Last update: $Date$
 * by : $Author$
 */
public class WikittyServiceAuthenticationLDAP extends WikittyServiceAuthenticationAbstract {

    /** to use log facility, just put in your code: log.info(\"...\"); */
    static private Log log = LogFactory.getLog(WikittyServiceAuthenticationLDAP.class);
    /** use to trace time of security code, timelog must not include delegator
     * time in this class */
    final static private TimeLog timeLog = new TimeLog(WikittyServiceAuthenticationLDAP.class);

    protected Properties jndiProp;
    protected String ldapLoginPattern;

    public WikittyServiceAuthenticationLDAP(ApplicationConfig config, WikittyService ws) {
        super(config, ws);

        long timeToLogInfo = config.getOptionAsInt(WikittyConfigOption.
                WIKITTY_SERVICE_TIME_TO_LOG_INFO.getKey());
        long timeToLogWarn = config.getOptionAsInt(WikittyConfigOption.
                WIKITTY_SERVICE_TIME_TO_LOG_WARN.getKey());
        timeLog.setTimeToLogInfo(timeToLogInfo);
        timeLog.setTimeToLogWarn(timeToLogWarn);

        // on charge toutes les options jndi
        Properties jndiPropTmp = config.getOptionStartsWith(WikittyConfigOption
                .WIKITTY_SERVICE_AUTHENTICATION_LDAP_JNDI.getKey());

        jndiProp = new Properties();
        for (Enumeration e=(Enumeration)jndiPropTmp.propertyNames(); e.hasMoreElements();) {
            String key = e.nextElement();
            String value = jndiPropTmp.getProperty(key);
            int debut = WikittyConfigOption.WIKITTY_SERVICE_AUTHENTICATION_LDAP_JNDI.getKey().length();
            key = key.substring(debut);
            jndiProp.setProperty(key, value);
        }

        // on charge l'url du serveur ldap
        String serverUrl = config.getOption(
                WikittyConfigOption.WIKITTY_SERVICE_AUTHENTICATION_LDAP_SERVER.getKey());
        jndiProp.put(Context.PROVIDER_URL, serverUrl);

        // on charge le pattern des logins (DN)
        ldapLoginPattern = config.getOption(
                WikittyConfigOption.WIKITTY_SERVICE_AUTHENTICATION_LDAP_LOGIN_PATTERN.getKey());
    }

    protected boolean canCreateUser() {
        boolean result = config.getOptionAsBoolean(
                WikittyConfigOption.WIKITTY_SERVICE_AUTHENTICATION_LDAP_AUTOCREATE_USER.getKey());
        return result;
    }

    @Override
    public String login(String login, String password) {
        long start = TimeLog.getTime();

        Wikitty user = null;
        String tokenId;

        WikittyQuery criteria = new WikittyQueryMaker()
                .eq(WikittyUser.FQ_FIELD_WIKITTYUSER_LOGIN, login).end();
        String userId = getAnonymousClient().findByQuery(criteria);

        boolean authenticated = false;

        // si l'utilisateur existe deja ou qu'on pourra le creer alors on va
        // plus loin dans l'authentification
        if (canCreateUser() || userId != null) {

            String ldapLogin = String.format(ldapLoginPattern, login);

            // on fait une copie pour etre thread safe (si plusieurs thread appele
            // cette methode en meme temps
            Hashtable env = new Hashtable(jndiProp);
            env.put(Context.SECURITY_PRINCIPAL, ldapLogin);
            env.put(Context.SECURITY_CREDENTIALS, password);

            try {
                DirContext dirContext = new InitialDirContext(env);
                dirContext.close();
                authenticated = true;
            } catch (NamingException eee) {
                log.debug(String.format(
                        "Erreur lors de l'acces au serveur LDAP pour l'utilisateur %s -> %s",
                        login, ldapLogin), eee);
            }

            if (authenticated) {
                log.info(String.format(
                        "External authentication success for account '%s'", login));
                // authentification reussi
                // si l'utilisateur n'existe pas encore on le cree si autorise par la config
                if (userId == null) {
                    user = new WikittyImpl();
                    WikittyUserHelper.addExtension(user);
                    WikittyUserHelper.setLogin(user, login);
                    // on met un mot de passe genere car l'authentification
                    // est faite par un moyen externe. Si pour une raison
                    // celui-ci n'est pas active, il ne faut pas que l'utilisateur
                    // puisse se loguer avec une mot de passe reel (trouvable facilement)
                    String generatedPassword = "external-" + UUID.randomUUID();
                    WikittyUserHelper.setPassword(user, generatedPassword);
                    getDelegate().store(null, Collections.singletonList(user), false);
                    log.info(String.format(
                            "Automatic user creation for account '%s'", login));
                } else {
                // sinon on le charge
                    user = WikittyServiceEnhanced.restore(
                            getDelegate(), null, userId);
                }
            }
        }

        if (authenticated) {
            tokenId = getToken(user.getWikittyId());
        } else {
            throw new SecurityException("bad login or password");
        }

        timeLog.log(start, "login");
        return tokenId;
    }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy