org.eclipse.ecf.internal.provider.filetransfer.httpclient4.HttpClientProxyCredentialProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.ecf.internal.provider.filetransfer.httpclient4.HttpClientProxyCredentialProvider.java

Source

/*******************************************************************************
 * Copyright (c) 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Thomas Joiner - HttpClient 4 implementation
 *******************************************************************************/
package org.eclipse.ecf.internal.provider.filetransfer.httpclient4;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.Credentials;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.eclipse.ecf.core.util.Proxy;
import org.eclipse.ecf.core.util.ProxyAddress;
import org.eclipse.ecf.core.util.Trace;

public abstract class HttpClientProxyCredentialProvider implements CredentialsProvider {

    abstract protected Proxy getECFProxy();

    abstract protected Credentials getNTLMCredentials(Proxy proxy);

    private Map cachedCredentials;

    public HttpClientProxyCredentialProvider() {
        cachedCredentials = new ConcurrentHashMap<AuthScope, Credentials>();
    }

    public void setCredentials(AuthScope authscope, Credentials credentials) {
        if (authscope == null)
            throw new IllegalArgumentException("Authentication scope may not be null"); //$NON-NLS-1$
        this.cachedCredentials.put(authscope, credentials);
    }

    public Credentials getCredentials(AuthScope authscope) {
        Trace.entering(Activator.PLUGIN_ID, DebugOptions.METHODS_ENTERING, HttpClientProxyCredentialProvider.class,
                "getCredentials " + authscope); //$NON-NLS-1$

        // First check to see whether given authscope matches any authscope 
        // already cached.
        Credentials result = matchCredentials(this.cachedCredentials, authscope);
        // If we have a match, return credentials
        if (result != null)
            return result;
        // If we don't have a match, first get ECF proxy, if any
        Proxy proxy = getECFProxy();
        if (proxy == null)
            return null;

        // Make sure that authscope and proxy host and port match
        if (!matchAuthScopeAndProxy(authscope, proxy))
            return null;

        // Then match scheme, and get credentials from proxy (if it's scheme we know about)
        Credentials credentials = null;
        if ("ntlm".equalsIgnoreCase(authscope.getScheme())) { //$NON-NLS-1$
            credentials = getNTLMCredentials(proxy);
        } else if ("basic".equalsIgnoreCase(authscope.getScheme()) || //$NON-NLS-1$
                "digest".equalsIgnoreCase(authscope.getScheme())) { //$NON-NLS-1$
            final String proxyUsername = proxy.getUsername();
            final String proxyPassword = proxy.getPassword();
            // If credentials present for proxy then we're done
            if (proxyUsername != null) {
                credentials = new UsernamePasswordCredentials(proxyUsername, proxyPassword);
            }
        } else if ("negotiate".equalsIgnoreCase(authscope.getScheme())) { //$NON-NLS-1$
            Trace.trace(Activator.PLUGIN_ID,
                    "SPNEGO is not supported, if you can contribute support, please do so."); //$NON-NLS-1$
        } else {
            Trace.trace(Activator.PLUGIN_ID, "Unrecognized authentication scheme."); //$NON-NLS-1$
        }

        // Put found credentials in cache for next time
        if (credentials != null)
            cachedCredentials.put(authscope, credentials);

        return credentials;
    }

    private boolean matchAuthScopeAndProxy(AuthScope authscope, Proxy proxy) {
        ProxyAddress proxyAddress = proxy.getAddress();
        return (authscope.getHost().equals(proxyAddress.getHostName())
                && (authscope.getPort() == proxyAddress.getPort()));
    }

    private static Credentials matchCredentials(final Map<AuthScope, Credentials> map, final AuthScope authscope) {
        // see if we get a direct hit
        Credentials creds = map.get(authscope);
        if (creds == null) {
            // Nope.
            // Do a full scan
            int bestMatchFactor = -1;
            AuthScope bestMatch = null;
            for (AuthScope current : map.keySet()) {
                int factor = authscope.match(current);
                if (factor > bestMatchFactor) {
                    bestMatchFactor = factor;
                    bestMatch = current;
                }
            }
            if (bestMatch != null) {
                creds = map.get(bestMatch);
            }
        }
        return creds;
    }

    public void clear() {
        this.cachedCredentials.clear();
    }
}