From 5b39bdf68a5a0e31313ecd2be4d1a66a65b8c6ec Mon Sep 17 00:00:00 2001 From: Jonathan Bauer Date: Fri, 28 Nov 2014 17:03:40 +0100 Subject: initial commit of 'ecp-client-lean' from KIT --- .../edu/kit/scc/dei/ecplean/ECPAuthenticator.java | 167 +++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 src/main/java/edu/kit/scc/dei/ecplean/ECPAuthenticator.java (limited to 'src/main/java/edu/kit/scc/dei/ecplean/ECPAuthenticator.java') diff --git a/src/main/java/edu/kit/scc/dei/ecplean/ECPAuthenticator.java b/src/main/java/edu/kit/scc/dei/ecplean/ECPAuthenticator.java new file mode 100644 index 0000000..f6d1bb7 --- /dev/null +++ b/src/main/java/edu/kit/scc/dei/ecplean/ECPAuthenticator.java @@ -0,0 +1,167 @@ +package edu.kit.scc.dei.ecplean; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URI; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.xpath.XPathConstants; +import javax.xml.xpath.XPathException; + +import org.apache.http.HttpResponse; +import org.apache.http.ParseException; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.HttpGet; +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.w3c.dom.Node; +import org.xml.sax.SAXException; + +public class ECPAuthenticator extends ECPAuthenticatorBase { + + public ECPAuthenticator(DefaultHttpClient client, String username, String password, + URI idpEcpEndpoint, URI spUrl) { + super(client); + + authInfo = new ECPAuthenticationInfo(username, password, idpEcpEndpoint, spUrl); + authInfo.setAuthState(ECPAuthState.NOT_STARTED); + } + + public ECPAuthenticator(String username, String password, + URI idpEcpEndpoint, URI spUrl) { + this(new DefaultHttpClient(), username, password, idpEcpEndpoint, spUrl); + } + + public void authenticate() throws ECPAuthenticationException { + logger.info("Starting authentication"); + + logger.info("Contacting SP " + authInfo.getSpUrl()); + authInfo.setAuthState(ECPAuthState.INITIAL_PAOS_SP); + setChanged(); + notifyObservers(authInfo); + + logger.info("Sending initial SP Request"); + + HttpGet httpGet = new HttpGet(authInfo.getSpUrl().toString()); + httpGet.setHeader("Accept", "text/html; application/vnd.paos+xml"); + httpGet.setHeader("PAOS", "ver='urn:liberty:paos:2003-08';'urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp'"); + + HttpResponse httpResponse; + String responseBody; + try { + httpResponse = client.execute(httpGet); + responseBody = EntityUtils.toString(httpResponse.getEntity()); + } catch (ClientProtocolException e) { + logger.debug("Initial SP Request failed"); + throw new ECPAuthenticationException(e); + } catch (ParseException e) { + logger.debug("Initial SP Request failed"); + throw new ECPAuthenticationException(e); + } catch (IOException e) { + logger.debug("Initial SP Request failed"); + throw new ECPAuthenticationException(e); + } + + Document initResponse; + try { + initResponse = buildDocumentFromString(responseBody); + } catch (IOException e) { + logger.debug("Parsing SP Request failed"); + throw new ECPAuthenticationException(e); + } catch (ParserConfigurationException e) { + logger.debug("Parsing SP Request failed"); + throw new ECPAuthenticationException(e); + } catch (SAXException e) { + logger.debug("Parsing SP Request failed"); + throw new ECPAuthenticationException(e); + } + + String relayState; + try { + relayState = (String) queryDocument(initResponse, "//ecp:RelayState", XPathConstants.STRING); + } catch (XPathException e) { + logger.debug("Could not find relay state in PAOS answer from SP"); + throw new ECPAuthenticationException(e); + } + logger.info("Got relayState: " + relayState); + String responseConsumerUrl; + try { + responseConsumerUrl = (String) queryDocument(initResponse, "/S:Envelope/S:Header/paos:Request/@responseConsumerURL", XPathConstants.STRING); + } catch (XPathException e) { + logger.debug("Could not find response consumer url in PAOS answer from SP"); + throw new ECPAuthenticationException(e); + } + logger.info("Got responseConsumerUrl: " + responseConsumerUrl); + + Node firstChild = initResponse.getDocumentElement().getFirstChild(); + initResponse.getDocumentElement().removeChild(firstChild); + + Document idpResponse = authenticateIdP(initResponse); + + String assertionConsumerUrl; + try { + assertionConsumerUrl = (String) queryDocument(idpResponse, "/S:Envelope/S:Header/ecp:Response/@AssertionConsumerServiceURL", XPathConstants.STRING); + } catch (XPathException e) { + logger.debug("Could not find assertion consumer url in answer from IdP"); + throw new ECPAuthenticationException(e); + } + logger.info("Got assertionConsumerUrl: " + assertionConsumerUrl); + + if (! assertionConsumerUrl.equals(responseConsumerUrl)) { + throw new ECPAuthenticationException("Assertion- and ResponseConsumerURL don't match"); + } + + idpResponse.getDocumentElement().getFirstChild().getFirstChild().setTextContent(relayState); + + logger.info("Sending Assertion to SP"); + HttpPost httpPost = new HttpPost(assertionConsumerUrl); + httpPost.setHeader("Content-Type", "application/vnd.paos+xml"); + try { + httpPost.setEntity(new StringEntity(documentToString(idpResponse))); + httpResponse = client.execute(httpPost); + responseBody = EntityUtils.toString(httpResponse.getEntity()); + } catch (UnsupportedEncodingException e) { + logger.debug("Could not post assertion back to SP"); + throw new ECPAuthenticationException(e); + } catch (TransformerConfigurationException e) { + logger.debug("Could not post assertion back to SP"); + throw new ECPAuthenticationException(e); + } catch (ClientProtocolException e) { + logger.debug("Could not post assertion back to SP"); + throw new ECPAuthenticationException(e); + } catch (ParseException e) { + logger.debug("Could not post assertion back to SP"); + throw new ECPAuthenticationException(e); + } catch (TransformerException e) { + logger.debug("Could not post assertion back to SP"); + throw new ECPAuthenticationException(e); + } catch (IOException e) { + logger.debug("Could not post assertion back to SP"); + throw new ECPAuthenticationException(e); + } + + logger.info("Requesting original URL"); + httpGet = new HttpGet(authInfo.getSpUrl().toString()); + try { + httpResponse = client.execute(httpGet); + responseBody = EntityUtils.toString(httpResponse.getEntity()); + + logger.info(responseBody); + } catch (ClientProtocolException e) { + logger.debug("Could not request original URL"); + throw new ECPAuthenticationException(e); + } catch (ParseException e) { + logger.debug("Could not request original URL"); + throw new ECPAuthenticationException(e); + } catch (IOException e) { + logger.debug("Could not request original URL"); + throw new ECPAuthenticationException(e); + } + + } +} -- cgit v1.2.3-55-g7522