org.aselect.server.request.handler.xsaml20.ProxyHTTPMetadataProvider.java Source code

Java tutorial

Introduction

Here is the source code for org.aselect.server.request.handler.xsaml20.ProxyHTTPMetadataProvider.java

Source

/*
 * * Copyright (c) Anoigo. All rights reserved.
 *
 * A-Select is a trademark registered by SURFnet bv.
 *
 * This program is distributed under the EUPL 1.0 (http://osor.eu/eupl)
 * See the included LICENSE file for details.
 *
 * If you did not receive a copy of the LICENSE
 * please contact Anoigo. (http://www.anoigo.nl) 
 * 
 * Created on 20090615
 *  This class provides a "wrapper" for the  HTTPMetadataProvider class
 *  to support a forward proxy server
 *  
 *  Unfortunately all properties in opensaml HTTPMetadataProvider are private
 *  and for most of them there are no getters/setters
 *  Life would have been much easier if there had been :P
 *  
 *  This class should be removed as soon as opensaml supports forward proxies
 */
package org.aselect.server.request.handler.xsaml20;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Level;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.aselect.server.log.ASelectSystemLogger;
import org.aselect.system.logging.SystemLogger;
import org.opensaml.saml2.metadata.provider.HTTPMetadataProvider;
import org.opensaml.saml2.metadata.provider.MetadataProviderException;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.io.UnmarshallingException;

/**
 * @author Remy Hanswijk
 */
public class ProxyHTTPMetadataProvider extends HTTPMetadataProvider {

    /** HTTP Client used to pull the metadata. */
    protected HttpClient proxyhttpClient;
    /** URL scope that requires authentication. */
    private AuthScope proxyauthScope;

    protected SystemLogger _systemLogger;

    /**
     * The Constructor.
     * 
     * @param metadataURL
     *            the metadata url
     * @param requestTimeout
     *            the request timeout
     * @param proxyHost
     *            the proxy host
     * @param proxyPort
     *            the proxy port
     * @throws MetadataProviderException
     *             the metadata provider exception
     */
    public ProxyHTTPMetadataProvider(String metadataURL, int requestTimeout, String proxyHost, int proxyPort)
            throws MetadataProviderException {

        super(metadataURL, requestTimeout);

        _systemLogger = ASelectSystemLogger.getHandle();
        HttpClientParams clientParams = new HttpClientParams();
        clientParams.setSoTimeout(requestTimeout);
        proxyhttpClient = new HttpClient(clientParams);
        proxyhttpClient.getHostConfiguration().setProxy(proxyHost, proxyPort);
        URI l_metadataURI;
        try {
            l_metadataURI = new URI(getMetadataURI());
        } catch (URISyntaxException e) {
            throw new MetadataProviderException("Illegal URL syntax", e);
        }

        proxyauthScope = new AuthScope(l_metadataURI.getHost(), l_metadataURI.getPort());

        // commons-http-client >= 4.0 might use:
        // ProxySelectorRoutePlanner routePlanner = new ProxySelectorRoutePlanner(
        // httpclient.getConnectionManager().getSchemeRegistry(),
        // ProxySelector.getDefault());
        // httpclient.setRoutePlanner(routePlanner);

        // or:
        // HttpHost proxy = new HttpHost(proxyHost, proxyPort);
        // getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, proxy);

    }

    /**
     * Sets the username and password used to access the metadata URL. To disable BASIC authentication set the username
     * and password to null;
     * 
     * @param username
     *            the username
     * @param password
     *            the password
     */
    @Override
    public void setBasicCredentials(String username, String password) {
        if (username == null && password == null) {
            proxyhttpClient.getState().setCredentials(null, null);
        } else {
            UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
            proxyhttpClient.getState().setCredentials(proxyauthScope, credentials);
        }
    }

    /**
     * Gets the length of time in milliseconds to wait for the server to respond.
     * 
     * @return length of time in milliseconds to wait for the server to respond
     */
    @Override
    public int getRequestTimeout() {
        return proxyhttpClient.getParams().getSoTimeout();
    }

    /**
     * Sets the socket factory used to create sockets to the HTTP server.
     * 
     * @param newSocketFactory
     *            the socket factory used to produce sockets used to connect to the server
     * @see <a href="http://jakarta.apache.org/commons/httpclient/sslguide.html">HTTPClient SSL guide</a>
     */
    @Override
    public void setSocketFactory(ProtocolSocketFactory newSocketFactory) {
        Protocol protocol;
        try {
            protocol = new Protocol(new URI(getMetadataURI()).getScheme(), newSocketFactory,
                    new URI(getMetadataURI()).getPort());
            proxyhttpClient.getHostConfiguration().setHost(new URI(getMetadataURI()).getHost(),
                    new URI(getMetadataURI()).getPort(), protocol);
        } catch (URISyntaxException e) {
            _systemLogger.log(Level.INFO, "This should not happen, same URI has been instantiated before");
        }
    }

    /**
     * Fetches the metadata from the remote server and unmarshalls it.
     * 
     * @return the unmarshalled metadata
     * @throws IOException
     *             thrown if the metadata can not be fetched from the remote server
     * @throws UnmarshallingException
     *             thrown if the metadata can not be unmarshalled
     */
    @Override
    protected XMLObject fetchMetadata() throws IOException, UnmarshallingException {
        _systemLogger.log(Level.FINEST, "Fetching metadata document from remote server");

        GetMethod getMethod = new GetMethod(getMetadataURI());
        if (proxyhttpClient.getState().getCredentials(proxyauthScope) != null) {
            _systemLogger.log(Level.FINEST, "Using BASIC authentication when retrieving metadata");
            getMethod.setDoAuthentication(true);
        }
        proxyhttpClient.executeMethod(getMethod);

        _systemLogger.log(Level.FINER,
                "Retrieved the following metadata document\n{}" + getMethod.getResponseBodyAsString());
        XMLObject metadata = unmarshallMetadata(getMethod.getResponseBodyAsStream());

        _systemLogger.log(Level.FINEST, "Unmarshalled metadata from remote server");
        return metadata;

    }

}