Skip to content

Instantly share code, notes, and snippets.

@spalladino
Created September 19, 2012 18:40
Show Gist options
  • Select an option

  • Save spalladino/3751392 to your computer and use it in GitHub Desktop.

Select an option

Save spalladino/3751392 to your computer and use it in GitHub Desktop.
OneLogin SAML Java client with attributes support
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="com.onelogin.*,com.onelogin.saml.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>SAML Assertion Page</title>
</head>
<body>
<%
String certificateS ="LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxekNDQXhTZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBRENCaGpFTE1Ba0dBMVVFQmhNQ1FWVXgKRERBS0JnTlZCQWdUQTA1VFZ6RVBNQTBHQTFVRUJ4TUdVM2xrYm1WNU1Rd3dDZ1lEVlFRS0RBTlFTVlF4Q1RBSApCZ05WQkFzTUFERVlNQllHQTFVRUF3d1BiR0YzY21WdVkyVndhWFF1WTI5dE1TVXdJd1lKS29aSWh2Y05BUWtCCkRCWnNZWGR5Wlc1alpTNXdhWFJBWjIxaGFXd3VZMjl0TUI0WERURXlNRFF5T0RBeU1qSXlPRm9YRFRNeU1EUXkKTXpBeU1qSXlPRm93Z1lZeEN6QUpCZ05WQkFZVEFrRlZNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVApCbE41Wkc1bGVURU1NQW9HQTFVRUNnd0RVRWxVTVFrd0J3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psCmJtTmxjR2wwTG1OdmJURWxNQ01HQ1NxR1NJYjNEUUVKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnYKYlRDQm56QU5CZ2txaGtpRzl3MEJBUUVGQUFPQmpRQXdnWWtDZ1lFQXVCeXdQTmxDMUZvcEdMWWZGOTZTb3RpSwo4Tmo2L25XMDg0TzRvbVJNaWZ6eTd4OTU1UkxFeTY3M3EyYWlKTkIzTHZFNlh2a3Q5Y0d0eHROb09YdzFnMlV2CkhLcGxkUWJyNmJPRWpMTmVETlc3ajBvYitKclJ2QVVPSzlDUmdkeXc1TUM2bHdxVlFRNUMxRG5hVC8yZlNCRmoKYXNCRlRSMjRkRXBmVHk4SGZLRUNBd0VBQWFPQ0FTVXdnZ0VoTUFrR0ExVWRFd1FDTUFBd0N3WURWUjBQQkFRRApBZ1VnTUIwR0ExVWREZ1FXQkJRTkJHbW10M3l0S3BjSmFCYVlOYm55VTJ4a2F6QVRCZ05WSFNVRUREQUtCZ2dyCkJnRUZCUWNEQVRBZEJnbGdoa2dCaHZoQ0FRMEVFQllPVkdWemRDQllOVEE1SUdObGNuUXdnYk1HQTFVZEl3U0IKcXpDQnFJQVVEUVJwcHJkOHJTcVhDV2dXbURXNThsTnNaR3VoZ1l5a2dZa3dnWVl4Q3pBSkJnTlZCQVlUQWtGVgpNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVEJsTjVaRzVsZVRFTU1Bb0dBMVVFQ2d3RFVFbFVNUWt3CkJ3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psYm1ObGNHbDBMbU52YlRFbE1DTUdDU3FHU0liM0RRRUoKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnZiWUlCQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9CZ1FBRQpjVlVQQlg3dVptenFaSmZ5K3RVUE9UNUltTlFqOFZFMmxlcmhuRmpuR1BIbUhJcWhwemdud0hRdWpKZnMvYTMwCjlXbTVxd2NDYUMxZU81Y1dqY0cweDNPamRsbHNnWURhdGw1R0F1bXRCeDhKM05oV1JxTlVnaXRDSWtRbHhISXcKVWZnUWFDdXNoWWdEREw1WWJJUWErK2VnQ2dwSVorVDBEajVvUmV3Ly9BPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=";
// user account specific settings. Import the certificate here
AccountSettings accountSettings = new AccountSettings();
accountSettings.setCertificate(certificateS);
Response samlResponse = new Response(accountSettings);
samlResponse.loadXmlFromBase64(request.getParameter("SAMLResponse"));
if (samlResponse.isValid()) {
// the signature of the SAML Response is valid. The source is trusted
java.io.PrintWriter writer = response.getWriter();
writer.write("OK!");
writer.write(samlResponse.getNameId()); // [email protected]
writer.write(samlResponse.getAttribute("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress")); // [email protected]
writer.write(samlResponse.getAttribute("http://notifiablediseas.es/identity/claims/conditioncodes")); // 10300, 10400, 10500
writer.flush();
} else {
// the signature of the SAML Response is not valid
java.io.PrintWriter writer = response.getWriter();
writer.write("Failed");
writer.flush();
}
%>
</body>
</html>
<%@page import="java.net.URLEncoder"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page import="com.onelogin.saml.*,com.onelogin.*" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Auth Request</title>
<%
// the appSettings object contain application specific settings used by the SAML library
AppSettings appSettings = new AppSettings();
// set the URL of the consume.jsp (or similar) file for this app. The SAML Response will be posted to this URL
appSettings.setAssertionConsumerServiceUrl("http://localhost:8080/java-saml/consume.jsp");
// set the issuer of the authentication request. This would usually be the URL of the issuing web application
appSettings.setIssuer("http://localhost:8080");
// the accSettings object contains settings specific to the users account.
// At this point, your application must have identified the users origin
AccountSettings accSettings = new AccountSettings();
// The URL at the Identity Provider where to the authentication request should be sent
accSettings.setIdpSsoTargetUrl("http://notifiablediseas.es/users/saml/sign_in");
// Generate an AuthRequest and send it to the identity provider
AuthRequest authReq = new AuthRequest(appSettings, accSettings);
String reqString = accSettings.getIdp_sso_target_url()+"?SAMLRequest=" + AuthRequest.getRidOfCRLF(URLEncoder.encode(authReq.getRequest(AuthRequest.base64),"UTF-8"));
response.sendRedirect(reqString);
%>
</head>
<body>
</body>
</html>
package com.onelogin.saml;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.xml.crypto.dsig.XMLSignature;
import javax.xml.crypto.dsig.XMLSignatureFactory;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.apache.commons.codec.binary.Base64;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import com.onelogin.AccountSettings;
public class Response {
private Document xmlDoc;
private AccountSettings accountSettings;
private Certificate certificate;
public Response(AccountSettings accountSettings) throws CertificateException {
this.accountSettings = accountSettings;
certificate = new Certificate();
certificate.loadCertificate(this.accountSettings.getCertificate());
}
public void loadXml(String xml) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory fty = DocumentBuilderFactory.newInstance();
fty.setNamespaceAware(true);
DocumentBuilder builder = fty.newDocumentBuilder();
ByteArrayInputStream bais = new ByteArrayInputStream(xml.getBytes());
xmlDoc = builder.parse(bais);
}
public void loadXmlFromBase64(String response) throws ParserConfigurationException, SAXException, IOException {
Base64 base64 = new Base64();
byte [] decodedB = base64.decode(response);
String decodedS = new String(decodedB);
loadXml(decodedS);
}
public boolean isValid() throws Exception {
NodeList nodes = xmlDoc.getElementsByTagNameNS(XMLSignature.XMLNS, "Signature");
if(nodes==null || nodes.getLength()==0){
throw new Exception("Can't find signature in document.");
}
X509Certificate cert = certificate.getX509Cert();
DOMValidateContext ctx = new DOMValidateContext(cert.getPublicKey() , nodes.item(0));
XMLSignatureFactory sigF = XMLSignatureFactory.getInstance("DOM");
XMLSignature xmlSignature = sigF.unmarshalXMLSignature(ctx);
return xmlSignature.validate(ctx);
}
public String getNameId() throws Exception {
NodeList nodes = xmlDoc.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "NameID");
if(nodes.getLength()==0){
throw new Exception("No name id found in document");
}
return nodes.item(0).getTextContent();
}
public String getAttribute(String element) throws Exception {
NodeList nodes = xmlDoc.getElementsByTagNameNS("urn:oasis:names:tc:SAML:2.0:assertion", "Attribute");
for(int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getAttributes().getNamedItem("Name").getTextContent().equalsIgnoreCase(element)) {
return node.getFirstChild().getTextContent();
}
}
throw new Exception("No " + element + " found in document");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment