Wednesday, February 23, 2011

Resolve an artifact with OpenSAML

In my case the, after the sign on at the IdP is completed, the user is redirected to my AssertionConsumerService defined in meta data. The IdP sends an artifact back as a parameter.The artifact is a label pointing to the actual user data/login information(the assertion) at the IdP. The user data is not sent in the HTTP request of security reasons. Instead the consumer servlet send a Artifact Resolve Request over a SOAP back channel to get the data.

Here is an example of a servlet sending ArtifactResolveRequest and receiving an ArtifactResolveResponse.

 
private Envelope sendArtifactResolve(final ArtifactResolve artifactResolve) throws SOAPException, SecurityException, CertificateEncodingException,
  MarshallingException, SignatureException, IllegalAccessException {
  Envelope envelope = SAMLUtil.wrapInSOAPEnvelope(artifactResolve);

  BasicSOAPMessageContext soapContext = new BasicSOAPMessageContext();
  soapContext.setOutboundMessage(envelope);
  HttpClientBuilder clientBuilder = new HttpClientBuilder();
  HttpSOAPClient soapClient = new HttpSOAPClient(clientBuilder.buildClient(), new BasicParserPool());

  String artifactResolutionServiceURL = null;
  for (ArtifactResolutionService ars : SAMLMetaData.getIdpEntityDescriptor().getIDPSSODescriptor(SAMLConstants.SAML20P_NS)
      .getArtifactResolutionServices()) {
    if (ars.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) {
       artifactResolutionServiceURL = ars.getLocation();
    }
  }

  soapClient.send(artifactResolutionServiceURL, soapContext);

  return (Envelope)soapContext.getInboundMessage();
}

private ArtifactResolve generateArtifactResolve(final String artifactString) throws CertificateEncodingException, MarshallingException, SignatureException, IllegalArgumentException,  java.lang.SecurityException, IllegalAccessException {
  ArtifactResolve artifactResolve = SAMLUtil.buildSAMLObjectWithDefaultName(ArtifactResolve.class);

  Issuer issuer = SAMLUtil.buildSAMLObjectWithDefaultName(Issuer.class);
  issuer.setValue(EvoteProperties.getProperty("SPEntityId"));
  artifactResolve.setIssuer(issuer);
  artifactResolve.setIssueInstant(new DateTime());

  artifactResolveId = SAMLUtil.getSecureRandomIdentifier();
  artifactResolve.setID(artifactResolveId);

  for (ArtifactResolutionService sss : metaData.getIdpEntityDescriptor().getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getArtifactResolutionServices()) {
    if (sss.getBinding().equals(SAMLConstants.SAML2_SOAP11_BINDING_URI)) {
      artifactResolve.setDestination(sss.getLocation());
    }
  }

  Artifact artifact = SAMLUtil.buildSAMLObjectWithDefaultName(Artifact.class);
  artifact.setArtifact(artifactString);
  artifactResolve.setArtifact(artifact);

  return artifactResolve;
 }


ArtifactResolveRequest sent:

my-alias
AAQAAKHWNqF94IiJ1SjFRLxjyBBxq3RIkRN7/tJdnT2sFDU1tUtBRKJQMDE=



This is the resulting ArtifactResponse in my case:

IDP-alias





IDP-alias





IDP-alias

5VkzP/MZ1PMJ62o45/7DdFms9y7K






my-alias




urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport




03011700143


something@test.com


546848134886







Further reading

My book, A Guide to OpenSAML, covers the artifact resolution and the rest of the SAML authentication process in detail. It also covers encryption, digital signatures, SAML in general and more.

A Guide to OpenSAML

10 comments:

  1. Hi Stefan,

    Thanks a lot for providing the code for artifact resolution service.
    I was looking for some sample around this, and found this to be really useful.
    One question:
    Is "AAQAAKHWNqF94IiJ1SjFRLxjyBBxq3RIkRN7/tJdnT2sFDU1tUtBRKJQMDE=" received from IDP as part of SAMLArt request parameter (using HTTP GET)?

    Please can you also provide the list of imports that you used for the code.
    Also please provide the code sample from SAMLUtil, SAMLMetaData (looks like these are not from OpenSAML or 3rd party API).

    Thanks Again,
    Rajesh

    ReplyDelete
    Replies
    1. In this case the artifact isent as a URL parameter in a HTTP redirect. The SAML specs also states that this can be done using HTTP post.
      https://www.oasis-open.org/committees/download.php/35387/sstc-saml-bindings-errata-2.0-wd-05-diff.pdf

      The SAMLMetaData is basically just a wrapper for a MetadataProvider. More info on parsing metadata can be found here
      http://mylifewithjava.blogspot.no/2012/02/reading-metadata-with-opensaml.html

      The methods of the SAMLUtil can be found here
      http://mylifewithjava.blogspot.no/2011/04/convenience-methods-for-opensaml.html

      Delete
  2. Hello Stefan,
    Thx a lot for your post.

    Can you provide full code from SAMLUtil class, I will be very grateful.

    Łukasz

    ReplyDelete
    Replies
    1. The methods are here http://mylifewithjava.blogspot.no/2011/04/convenience-methods-for-opensaml.html

      Delete
    2. I try to find wrapInSOAPEnvelope source code ...

      Delete
  3. Hi stefan, Can you let me know how to authenticate the user in soap communication . Say suppose the idp is expecting the username and password for the soap communication where can i enter those values.
    I have done some R&D and found that client builder accepts some username and password but they are proxy related. Please let me know

    ReplyDelete
    Replies
    1. I'm sorry I have not done any work with this. The specification is here https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=wss and you can find much info on google but I have no help for you.

      Delete
  4. Hi Stefan , Can you tell me how to communicate opensaml SOAP over a SSL. I know we need to provide TLSProtocolSocketFactory . My app is Sp and trying to communicate to IDP over ssl . So is the IDP public key enough to communicate ? if yes how do i create TLSProtocolSocketFactory using the public key ?

    ReplyDelete
    Replies
    1. Sorry I dont know anything about this either. But I suspect you wont be able to use the IDP public key used in opensaml

      Delete
  5. Hi Stefan:

    I just tried to paid your book through paypal, but it didn't show if payment is successful or any download link. What's successful payment should look like?

    ReplyDelete