import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.joda.time.DateTime;
import org.opensaml.Configuration;
import org.opensaml.DefaultBootstrap;
import org.opensaml.common.SAMLVersion;
import org.opensaml.saml2.core.Assertion;
import org.opensaml.saml2.core.Attribute;
import org.opensaml.saml2.core.AttributeStatement;
import org.opensaml.saml2.core.AuthnContextClassRef;
import org.opensaml.saml2.core.AuthnContextComparisonTypeEnumeration;
import org.opensaml.saml2.core.AuthnRequest;
import org.opensaml.saml2.core.Issuer;
import org.opensaml.saml2.core.LogoutRequest;
import org.opensaml.saml2.core.NameID;
import org.opensaml.saml2.core.NameIDPolicy;
import org.opensaml.saml2.core.RequestAbstractType;
import org.opensaml.saml2.core.RequestedAuthnContext;
import org.opensaml.saml2.core.Response;
import org.opensaml.saml2.core.SessionIndex;
import org.opensaml.saml2.core.impl.AuthnContextClassRefBuilder;
import org.opensaml.saml2.core.impl.AuthnRequestBuilder;
import org.opensaml.saml2.core.impl.IssuerBuilder;
import org.opensaml.saml2.core.impl.LogoutRequestBuilder;
import org.opensaml.saml2.core.impl.NameIDBuilder;
import org.opensaml.saml2.core.impl.NameIDPolicyBuilder;
import org.opensaml.saml2.core.impl.RequestedAuthnContextBuilder;
import org.opensaml.saml2.core.impl.SessionIndexBuilder;
import org.opensaml.xml.ConfigurationException;
import org.opensaml.xml.XMLObject;
import org.opensaml.xml.XMLObjectBuilder;
import org.opensaml.xml.XMLObjectBuilderFactory;
import org.opensaml.xml.io.Marshaller;
import org.opensaml.xml.io.MarshallingException;
import org.opensaml.xml.io.Unmarshaller;
import org.opensaml.xml.io.UnmarshallerFactory;
import org.opensaml.xml.io.UnmarshallingException;
import org.opensaml.xml.util.Base64;
import org.opensaml.xml.util.XMLHelper;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import com.opensymphony.xwork2.util.logging.Logger;
import com.opensymphony.xwork2.util.logging.LoggerFactory;
public class SAMLConsumer {
  Â
   private static final Logger logger = LoggerFactory.getLogger(SAMLConsumer.class);
   private static boolean isBootstraped = false;
   private static final String ISSUER_URL = "test.com";
   private static final String CONSUMER_URL = "http://localhost:8080/test.com/home.jsp";
   private static final String NAME_SPACE_URI_ISSUER = "urn:oasis:names:tc:SAML:2.0:assertion";
   private static final String NAME_SPACE_URI_AUTH = "urn:oasis:names:tc:SAML:2.0:protocol";
   private static final String SAML_TRANSPORT_TYPE_PWD_PROTECTED = "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport";
   private static final String SAML_TRANSPORT_PROTOCOL_BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST";
  Â
   private static final String LOCAL_NAME_ISSUER = "Issuer";
   private static final String LOCAL_NAME_AUTHRQ = "AuthnRequest";
   private static final String NAME_SPACE_PREFIX = "samlp";
   private static final String AUTH_CNTXT_REF = "AuthnContextClassRef";
   private static final String SAML = "saml";
  Â
   public static String buildLoginRequest() throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException, MarshallingException, IOException {
      logger.info("started");
      IssuerBuilder issuerBuilder = new IssuerBuilder();
      Issuer issuer = issuerBuilder.buildObject(NAME_SPACE_URI_ISSUER, LOCAL_NAME_ISSUER, "samlp");
      issuer.setValue(ISSUER_URL);
     Â
      NameIDPolicyBuilder nameIdPolicyBuilder = new NameIDPolicyBuilder();
      NameIDPolicy nameIdPolicy = nameIdPolicyBuilder.buildObject();
      nameIdPolicy.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent");
      nameIdPolicy.setSPNameQualifier("Isser");
      nameIdPolicy.setAllowCreate(new Boolean(true));
     Â
      AuthnContextClassRefBuilder authnContextClassRefBuilder = new AuthnContextClassRefBuilder();
      AuthnContextClassRef authnContextClassRef =
                                                 authnContextClassRefBuilder.buildObject(NAME_SPACE_URI_ISSUER,
                                                       AUTH_CNTXT_REF, SAML);
      authnContextClassRef.setAuthnContextClassRef(SAML_TRANSPORT_TYPE_PWD_PROTECTED);
     Â
      RequestedAuthnContextBuilder requestedAuthnContextBuilder =
                                             new RequestedAuthnContextBuilder();
      RequestedAuthnContext requestedAuthnContext = requestedAuthnContextBuilder.buildObject();
      requestedAuthnContext.setComparison(AuthnContextComparisonTypeEnumeration.EXACT);
      requestedAuthnContext.getAuthnContextClassRefs().add(authnContextClassRef);
     Â
      DateTime issueInstant = new DateTime();
      AuthnRequestBuilder authnRequestBuilder = new AuthnRequestBuilder();
      AuthnRequest authnRequest = authnRequestBuilder.buildObject(NAME_SPACE_URI_AUTH, LOCAL_NAME_AUTHRQ, NAME_SPACE_PREFIX);
      authnRequest.setForceAuthn(new Boolean(false));
      authnRequest.setIsPassive(new Boolean(false));
      authnRequest.setIssueInstant(issueInstant);
      authnRequest.setProtocolBinding(SAML_TRANSPORT_PROTOCOL_BINDING);
      authnRequest.setAssertionConsumerServiceURL(CONSUMER_URL);
      authnRequest.setIssuer(issuer);
      authnRequest.setNameIDPolicy(nameIdPolicy);
      authnRequest.setRequestedAuthnContext(requestedAuthnContext);
     Â
      String authReqRandomId = Integer.toHexString(new Double(Math.random()).intValue());
     Â
      authnRequest.setID(authReqRandomId);
      authnRequest.setVersion(SAMLVersion.VERSION_20);
           Â
      return marshall(authnRequest);
     Â
   }
  Â
   public static String buildLogoutRequest(String user) throws MarshallingException, IOException {
      LogoutRequest logoutReq = new LogoutRequestBuilder().buildObject();
      logoutReq.setID(createID());
      DateTime issueInstant = new DateTime();
      logoutReq.setIssueInstant(issueInstant);
      logoutReq.setNotOnOrAfter(new DateTime(issueInstant.getMillis() + 5 * 60 * 1000));
      IssuerBuilder issuerBuilder = new IssuerBuilder();
      Issuer issuer = issuerBuilder.buildObject();
      issuer.setValue(ISSUER_URL);
      logoutReq.setIssuer(issuer);
      NameID nameId = new NameIDBuilder().buildObject();
      nameId.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:entity");
      nameId.setValue(user);
      logoutReq.setNameID(nameId);
      SessionIndex sessionIndex = new SessionIndexBuilder().buildObject();
      sessionIndex.setSessionIndex(UIDGenerator.generateUID());
      logoutReq.getSessionIndexes().add(sessionIndex);
      logoutReq.setReason("Single Logout");
      return marshall(logoutReq);
   }
  Â
   private static String marshall(RequestAbstractType authnRequest) throws MarshallingException, IOException {
      doBootstrap();
      Marshaller marshaller = Configuration.getMarshallerFactory().getMarshaller(authnRequest);
      Element authDOM = marshaller.marshall(authnRequest);
     Â
     Â
      StringWriter rspWrt = new StringWriter();
      XMLHelper.writeNode(authDOM, rspWrt);
      String requestMessage = rspWrt.toString();
     Â
      System.out.println(requestMessage);
             Â
      Deflater deflater = new Deflater(Deflater.DEFLATED, true);
      ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
      DeflaterOutputStream deflaterOutputStream = new DeflaterOutputStream(byteArrayOutputStream, deflater);
      deflaterOutputStream.write(requestMessage.getBytes());
      deflaterOutputStream.close();
             Â
      /* Encoding the compressed message */
      String encodedRequestMessage = Base64.encodeBytes(byteArrayOutputStream.toByteArray(), Base64.DONT_BREAK_LINES);
      String encodedAuthnRequest = URLEncoder.encode(encodedRequestMessage,"UTF-8").trim();;
     Â
      return encodedAuthnRequest;
   }
  Â
  Â
   public static <T> T createSAMLObject(final Class<T> clazz) throws IllegalArgumentException, SecurityException, IllegalAccessException, NoSuchFieldException {
      XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();
     Â
      QName defaultElementName = (QName)clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null);
      Map<QName, XMLObjectBuilder> builderMap= builderFactory.getBuilders();
      System.out.println("is nul " + builderMap.get(defaultElementName));
     Â
      return null;
   }
  Â
   private static void doBootstrap() {
      if(!isBootstraped) {
         try {
            DefaultBootstrap.bootstrap();
            isBootstraped = true;
         } catch (ConfigurationException e) {
            logger.error("Error calling bootstrap", e);
         }
      }
   }
  Â
   public static Map<String, String> processResponse(String response) {
      XMLObject resp = null;
     Â
      try {
         resp = unmarshall(response);
      } catch (ConfigurationException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } catch (ParserConfigurationException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } catch (SAXException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      } catch (UnmarshallingException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
     Â
      return getResult(resp);
     Â
   }
  Â
   private static XMLObject unmarshall(String responseMessage) throws ConfigurationException,
                     ParserConfigurationException, SAXException, IOException, UnmarshallingException {
     Â
      doBootstrap();
      DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
      documentBuilderFactory.setNamespaceAware(true);
      DocumentBuilder docBuilder = documentBuilderFactory.newDocumentBuilder();
     Â
      byte[] base64DecodedResponse = Base64.decode(responseMessage.trim());
     Â
      System.out.println(new String(base64DecodedResponse));
     Â
      ByteArrayInputStream is = new ByteArrayInputStream(base64DecodedResponse);
     Â
      Document document = docBuilder.parse(is);
      Element element = document.getDocumentElement();
      UnmarshallerFactory unmarshallerFactory = Configuration.getUnmarshallerFactory();
      Unmarshaller unmarshaller = unmarshallerFactory.getUnmarshaller(element);
      return unmarshaller.unmarshall(element);
     Â
   }
  Â
   private static Map<String, String> getResult(XMLObject responseXmlObj) {
      if (responseXmlObj.getDOM().getNodeName().equals("saml2p:LogoutResponse")) {
         logger.error("user logout");
         return null;
      }
      Response response = (Response) responseXmlObj;
      logger.info("SAML resp" + response);
      Assertion assertion = response.getAssertions().get(0);
      Map<String, String> resutls = new HashMap<String, String>();
      /*
      * If the request has failed, the IDP shouldn't send an assertion.
      * SSO profile spec 4.1.4.2 <Response> Usage
      */
      if (assertion != null) {
         String subject = assertion.getSubject().getNameID().getValue();
         resutls.put("Subject", subject); // get the subject
         List<AttributeStatement> attributeStatementList = assertion.getAttributeStatements();
         if (attributeStatementList != null) {
            // we have received attributes of user
            Iterator<AttributeStatement> attribStatIter = attributeStatementList.iterator();
            while (attribStatIter.hasNext()) {
               AttributeStatement statment = attribStatIter.next();
               List<Attribute> attributesList = statment.getAttributes();
               Iterator<Attribute> attributesIter = attributesList.iterator();
               while (attributesIter.hasNext()) {
                  Attribute attrib = attributesIter.next();
                  Element value = attrib.getAttributeValues().get(0).getDOM();
                  String attribValue = value.getTextContent();
                  resutls.put(attrib.getName(), attribValue);
               }
            }
         }
      }
      return resutls;
   }
  Â
   public static String createID() {
       byte[] bytes = new byte[20]; // 160 bit
      Â
       new Random().nextBytes(bytes);
      Â
       char[] charMapping = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'};
       char[] chars = new char[40];
       for (int i = 0; i < bytes.length; i++) {
           int left = (bytes[i] >> 4) & 0x0f;
           int right = bytes[i] & 0x0f;
           chars[i * 2] = charMapping[left];
           chars[i * 2 + 1] = charMapping[right];
       }
       return String.valueOf(chars);
   }
  Â
}