Package org.apache.ldap.server.authn

Source Code of org.apache.ldap.server.authn.AuthenticationService$TrustedPrincipalWrapper

/*
*   Copyright 2004 The Apache Software Foundation
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*
*/
package org.apache.ldap.server.authn;


import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchControls;

import org.apache.ldap.common.exception.LdapAuthenticationException;
import org.apache.ldap.common.exception.LdapAuthenticationNotSupportedException;
import org.apache.ldap.common.filter.ExprNode;
import org.apache.ldap.common.message.ResultCodeEnum;
import org.apache.ldap.common.util.StringTools;
import org.apache.ldap.server.configuration.AuthenticatorConfiguration;
import org.apache.ldap.server.configuration.InterceptorConfiguration;
import org.apache.ldap.server.interceptor.Interceptor;
import org.apache.ldap.server.interceptor.NextInterceptor;
import org.apache.ldap.server.invocation.InvocationStack;
import org.apache.ldap.server.jndi.ContextFactoryConfiguration;
import org.apache.ldap.server.jndi.ServerContext;


/**
* An {@link Interceptor} that authenticates users.
*
* @author Apache Directory Project (dev@directory.apache.org)
* @author Alex Karasulu (akarasulu@apache.org)
* @author Trustin Lee (trustin@apache.org)
* @version $Rev: 226451 $, $Date: 2005-07-29 20:54:58 -0400 (Fri, 29 Jul 2005) $
*/
public class AuthenticationService implements Interceptor
{
    /** authenticators **/
    public Map authenticators = new HashMap();

    private ContextFactoryConfiguration factoryCfg;

    /**
     * Creates an authentication service interceptor.
     */
    public AuthenticationService()
    {
    }

    /**
     * Registers and initializes all {@link Authenticator}s to this service.
     */
    public void init( ContextFactoryConfiguration factoryCfg, InterceptorConfiguration cfg ) throws NamingException
    {
        this.factoryCfg = factoryCfg;

        // Register all authenticators
        Iterator i = factoryCfg.getStartupConfiguration().getAuthenticatorConfigurations().iterator();
        while( i.hasNext() )
        {
            try
            {
                this.register( ( AuthenticatorConfiguration ) i.next() );
            }
            catch ( Exception e )
            {
                destroy();
                throw ( NamingException ) new NamingException(
                        "Failed to register authenticator." ).initCause( e );
            }
        }
    }
   
    /**
     * Deinitializes and deregisters all {@link Authenticator}s from this service.
     */
    public void destroy()
    {
        Iterator i = new ArrayList( authenticators.values() ).iterator();
        while( i.hasNext() )
        {
            Iterator j = new ArrayList( ( Collection ) i.next() ).iterator();
            while( j.hasNext() )
            {
                unregister( ( Authenticator ) j.next() );
            }
        }
       
        authenticators.clear();
    }

    /**
     * Initializes the specified {@link Authenticator} and registers it to
     * this service.
     */
    private void register( AuthenticatorConfiguration cfg ) throws NamingException
    {
        cfg.getAuthenticator().init( factoryCfg, cfg );

        Collection authenticatorList = getAuthenticators( cfg.getAuthenticator().getAuthenticatorType() );
        if ( authenticatorList == null )
        {
            authenticatorList = new ArrayList();
            authenticators.put( cfg.getAuthenticator().getAuthenticatorType(), authenticatorList );
        }

        authenticatorList.add( cfg.getAuthenticator() );
    }

    /**
     * Deinitializes the specified {@link Authenticator} and deregisters it from
     * this service.
     */
    private void unregister( Authenticator authenticator )
    {
        Collection authenticatorList = getAuthenticators( authenticator.getAuthenticatorType() );

        if ( authenticatorList == null )
        {
            return;
        }

        authenticatorList.remove( authenticator );
       
        try
        {
            authenticator.destroy();
        }
        catch( Throwable t )
        {
            t.printStackTrace();
        }
    }

    /**
     * Returns the list of {@link Authenticator}s with the specified type.
     *
     * @return <tt>null</tt> if no authenticator is found.
     */
    private Collection getAuthenticators( String type )
    {
        Collection result = ( Collection ) authenticators.get( type );
        if( result != null && result.size() > 0 )
        {
            return result;
        }
        else
        {
            return null;
        }
    }
   

    public void add( NextInterceptor next, String upName, Name normName, Attributes entry ) throws NamingException
    {
        authenticate();
        next.add( upName, normName, entry );
    }


    public void delete( NextInterceptor next, Name name ) throws NamingException
    {
        authenticate();
        next.delete( name );
    }


    public Name getMatchedName( NextInterceptor next, Name dn, boolean normalized ) throws NamingException
    {
        authenticate();
        return next.getMatchedName( dn, normalized );
    }


    public Attributes getRootDSE( NextInterceptor next ) throws NamingException
    {
        authenticate();
        return next.getRootDSE();
    }


    public Name getSuffix( NextInterceptor next, Name dn, boolean normalized ) throws NamingException
    {
        authenticate();
        return next.getSuffix( dn, normalized );
    }


    public boolean hasEntry( NextInterceptor next, Name name ) throws NamingException
    {
        authenticate();
        return next.hasEntry( name );
    }


    public boolean isSuffix( NextInterceptor next, Name name ) throws NamingException
    {
        authenticate();
        return next.isSuffix( name );
    }


    public NamingEnumeration list( NextInterceptor next, Name base ) throws NamingException
    {
        authenticate();
        return next.list( base );
    }


    public Iterator listSuffixes( NextInterceptor next, boolean normalized ) throws NamingException
    {
        authenticate();
        return next.listSuffixes( normalized );
    }


    public Attributes lookup( NextInterceptor next, Name dn, String[] attrIds ) throws NamingException
    {
        authenticate();
        return next.lookup( dn, attrIds );
    }


    public Attributes lookup( NextInterceptor next, Name name ) throws NamingException
    {
        authenticate();
        return next.lookup( name );
    }


    public void modify( NextInterceptor next, Name name, int modOp, Attributes mods ) throws NamingException
    {
        authenticate();
        next.modify( name, modOp, mods );
    }


    public void modify( NextInterceptor next, Name name, ModificationItem[] mods ) throws NamingException
    {
        authenticate();
        next.modify( name, mods );
    }


    public void modifyRn( NextInterceptor next, Name name, String newRn, boolean deleteOldRn ) throws NamingException
    {
        authenticate();
        next.modifyRn( name, newRn, deleteOldRn );
    }


    public void move( NextInterceptor next, Name oriChildName, Name newParentName, String newRn, boolean deleteOldRn ) throws NamingException
    {
        authenticate();
        next.move( oriChildName, newParentName, newRn, deleteOldRn );
    }


    public void move( NextInterceptor next, Name oriChildName, Name newParentName ) throws NamingException
    {
        authenticate();
        next.move( oriChildName, newParentName );
    }


    public NamingEnumeration search( NextInterceptor next, Name base, Map env, ExprNode filter, SearchControls searchCtls ) throws NamingException
    {
        authenticate();
        return next.search( base, env, filter, searchCtls );
    }


    private void authenticate() throws NamingException
    {
        // check if we are already authenticated and if so we return making
        // sure first that the credentials are not exposed within context
        ServerContext ctx =
            ( ServerContext ) InvocationStack.getInstance().peek().getCaller();

        if ( ctx.getPrincipal() != null )
        {
            if ( ctx.getEnvironment().containsKey( Context.SECURITY_CREDENTIALS ) )
            {
                ctx.removeFromEnvironment( Context.SECURITY_CREDENTIALS );
            }
            return;
        }

        String authList = ( String ) ctx.getEnvironment().get( Context.SECURITY_AUTHENTICATION );

        if ( authList == null )
        {
            if ( ctx.getEnvironment().containsKey( Context.SECURITY_CREDENTIALS ) )
            {
                // authentication type is simple here

                authList = "simple";
            }
            else
            {
                // authentication type is anonymous

                authList = "none";
            }

        }

        authList = StringTools.deepTrim( authList );

        String[] auth = authList.split( " " );

        Collection authenticators = null;

        // pick the first matching authenticator type

        for ( int i=0; i<auth.length; i++)
        {
            authenticators = getAuthenticators( auth[i] );

            if ( authenticators != null )
            {
                break;
            }
        }

        if ( authenticators == null )
        {
            ctx.getEnvironment(); // shut's up idea's yellow light

            ResultCodeEnum rc = ResultCodeEnum.AUTHMETHODNOTSUPPORTED;

            throw new LdapAuthenticationNotSupportedException( rc );
        }

        // try each authenticators
        for ( Iterator i = authenticators.iterator(); i.hasNext(); )
        {
            try
            {
                Authenticator authenticator = ( Authenticator ) i.next();

                // perform the authentication

                LdapPrincipal authorizationId = authenticator.authenticate( ctx );

                // authentication was successful

                ctx.setPrincipal( new TrustedPrincipalWrapper( authorizationId ) );

                // remove creds so there is no security risk

                ctx.removeFromEnvironment( Context.SECURITY_CREDENTIALS );
                return;
            }
            catch ( LdapAuthenticationException e )
            {
                // authentication failed, try the next authenticator
            }
        }

        throw new LdapAuthenticationException();
    }


    /**
     * FIXME This doesn't secure anything actually.
     *
     * Created this wrapper to pass to ctx.setPrincipal() which is public for added
     * security.  This adds more security because an instance of this class is not
     * easily accessible whereas LdapPrincipals can be accessed easily from a context
     * althought they cannot be instantiated outside of the authn package.  Malicious
     * code may not be able to set the principal to what they would like but they
     * could switch existing principals using the now public ServerContext.setPrincipal()
     * method.  To avoid this we make sure that this metho takes a TrustedPrincipalWrapper
     * as opposed to the LdapPrincipal.  Only this service can create and call setPrincipal
     * with a TrustedPrincipalWrapper.
     */
    public final class TrustedPrincipalWrapper
    {
        /** the wrapped ldap principal */
        private final LdapPrincipal principal;


        /**
         * Creates a TrustedPrincipalWrapper around an LdapPrincipal.
         *
         * @param principal the LdapPrincipal to wrap
         */
        private TrustedPrincipalWrapper( LdapPrincipal principal )
        {
            this.principal = principal;
        }


        /**
         * Gets the LdapPrincipal this TrustedPrincipalWrapper wraps.
         *
         * @return the wrapped LdapPrincipal
         */
        public LdapPrincipal getPrincipal()
        {
            return principal;
        }
    }
}
TOP

Related Classes of org.apache.ldap.server.authn.AuthenticationService$TrustedPrincipalWrapper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.