summaryrefslogblamecommitdiffstats
path: root/src/main/java/edu/kit/scc/dei/ecplean/ECPAuthenticatorBase.java
blob: 7e080f6edb9e2bd501e34d6cb03e33dccfee6bca (plain) (tree)





















































































































































                                                                                                               
package edu.kit.scc.dei.ecplean;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.Observable;

import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathException;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public abstract class ECPAuthenticatorBase extends Observable {

	protected static Log logger = LogFactory.getLog(ECPAuthenticatorBase.class);
	protected ECPAuthenticationInfo authInfo;
	protected DefaultHttpClient client;
	protected DocumentBuilderFactory documentBuilderFactory;
	protected XPathFactory xpathFactory;
	protected NamespaceResolver namespaceResolver;
	protected TransformerFactory transformerFactory;

	public ECPAuthenticatorBase(DefaultHttpClient client) {
		this.client = client;
		
		documentBuilderFactory = DocumentBuilderFactory.newInstance();
		documentBuilderFactory.setNamespaceAware(true);
		
		xpathFactory = XPathFactory.newInstance();
		namespaceResolver = new NamespaceResolver();
		namespaceResolver.addNamespace("ecp", "urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp");
		namespaceResolver.addNamespace("S", "http://schemas.xmlsoap.org/soap/envelope/");
		namespaceResolver.addNamespace("paos", "urn:liberty:paos:2003-08");
		
		transformerFactory = TransformerFactory.newInstance();
	}

	public ECPAuthenticatorBase() {
		this(new DefaultHttpClient());
	}
	
	protected Document authenticateIdP(Document idpRequest) 
			throws ECPAuthenticationException   {
		logger.info("Sending initial IdP Request");
        client.getCredentialsProvider().setCredentials(
                new AuthScope(authInfo.getIdpEcpEndpoint().getHost(), authInfo.getIdpEcpEndpoint().getPort()),
                new UsernamePasswordCredentials(authInfo.getUsername(), authInfo.getPassword()));
        HttpPost httpPost = new HttpPost(authInfo.getIdpEcpEndpoint().toString());
		HttpResponse httpResponse;

		try {
			httpPost.setEntity(new StringEntity(documentToString(idpRequest)));
			httpResponse = client.execute(httpPost);
			
			if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_UNAUTHORIZED) {
				throw new ECPAuthenticationException("User not authorized");
			}
		} catch (UnsupportedEncodingException e) {
			logger.debug("Could not submit PAOS request to IdP");
			throw new ECPAuthenticationException(e);
		} catch (TransformerConfigurationException e) {
			logger.debug("Could not submit PAOS request to IdP");
			throw new ECPAuthenticationException(e);
		} catch (ClientProtocolException e) {
			logger.debug("Could not submit PAOS request to IdP");
			throw new ECPAuthenticationException(e);
		} catch (TransformerException e) {
			logger.debug("Could not submit PAOS request to IdP");
			throw new ECPAuthenticationException(e);
		} catch (IOException e) {
			logger.debug("Could not submit PAOS request to IdP");
			throw new ECPAuthenticationException(e);
		}

		String responseBody;
		try {
			responseBody = EntityUtils.toString(httpResponse.getEntity());
			return buildDocumentFromString(responseBody);		
		} catch (ParseException e) {
			logger.debug("Could not read response from IdP");
			throw new ECPAuthenticationException(e);
		} catch (IOException e) {
			logger.debug("Could not read response from IdP");
			throw new ECPAuthenticationException(e);
		} catch (SAXException e) {
			logger.debug("Could not read response from IdP");
			throw new ECPAuthenticationException(e);
		} catch (ParserConfigurationException e) {
			logger.debug("Could not read response from IdP");
			throw new ECPAuthenticationException(e);
		}		
	}
	
	protected Document buildDocumentFromString(String input)
			throws IOException, ParserConfigurationException, SAXException {
		DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder();
		return builder.parse(new InputSource(new StringReader(input)));
	}

	protected Object queryDocument(Document xmlDocument, String expression,
			QName returnType) throws XPathException {
		XPath xpath = xpathFactory.newXPath();
		xpath.setNamespaceContext(namespaceResolver);
		XPathExpression xPathExpression = xpath.compile(expression);
		return xPathExpression.evaluate(xmlDocument, returnType);
	}

	protected String documentToString(Document xmlDocument)
			throws TransformerConfigurationException, TransformerException {
		Transformer transformer = transformerFactory.newTransformer();

		StreamResult result = new StreamResult(new StringWriter());
		DOMSource source = new DOMSource(xmlDocument);
		transformer.transform(source, result);

		return result.getWriter().toString();
	}

	public DefaultHttpClient getHttpClient() {
		return client;
	}

}