Friday, April 1, 2011

Convenience methods for OpenSAML


Creating SAML objects.

This is implementations of some of the methods in the SAMLUtil class referenced in other examples.

OpenSAML has a bit struggling way to create SAML objects using a factory pattern.

The normal way to create a SAML object is like this.

XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();

Assertion assertion = (Assertion)builderFactory
      .getBuilder(Assertion.DEFAULT_ELEMENT_NAME)
      .buildObject(Assertion.DEFAULT_ELEMENT_NAME);

Normaly the default name of the class is used so it seams redundant to write thsi out al the time.
With generics in JavaSE6 we can make this a lot easier.

public static <T> T createSAMLObject(final Class<T> clazz) {
 XMLObjectBuilderFactory builderFactory = Configuration.getBuilderFactory();

 QName defaultElementName = (QName)clazz.getDeclaredField("DEFAULT_ELEMENT_NAME").get(null);
 T object = (T)builderFactory.getBuilder(defaultElementName).buildObject(defaultElementName);

return object;
}

By putting something like this in a utility class we can now create our SAML objects like this

Assertion assertion = UtilityClass.createSAMLObject(Assertion.class);

Logging

The ability to in a nice way log the raw SAML messages i also very important, so I created my own logging method in a utility class. But after using it for a while I learned that I don't have to.

The OpenSAML library uses the log4j logging framework. By setting the threshold level, of the OpenSAML package ,to debug in the log4j properties file, you get all of the SAML messages to and from your application in your log file.
You also get other useful information, so log4j is definitely the way to go.

11 comments:

  1. Any reason why this doesn't work on the class Endpoint?

    ReplyDelete
    Replies
    1. I have never had a reason to try so I dont know, seems there is no builder for it

      Delete
    2. This is probably becaouse you are supposed to instansiate one of the implmenting classes: ArtifactResolutionServiceImpl, AssertionConsumerServiceImpl, AssertionIDRequestServiceImpl, AttributeServiceImpl, AuthnQueryServiceImpl, AuthzServiceImpl, DiscoveryResponseImpl, EndpointImpl, IndexedEndpointImpl, ManageNameIDServiceImpl, NameIDMappingServiceImpl, SingleLogoutServiceImpl, SingleSignOnServiceImpl

      Delete
  2. Probably doesn't work because the formatting is all messed up in the post. While it's a nice mental exercise to figure out what author meant by this code, it gets old quickly. Please verify the formatting before posting.

    ReplyDelete
    Replies
    1. Yep seems to that it cant handle generics, any tips for a better formater?

      Delete
    2. Fixed it, had to do some manual escaping

      Delete
  3. May I know the version of OpenSaml jar used for this example. I am getting NullPointerException while building Assertion.

    ReplyDelete
    Replies
    1. Hi, try this http://mylifewithjava.blogspot.no/2014/05/nullpointer-exception-in-opensaml.html

      Delete
  4. Iam New to openSAML

    I have created new application which has some products list, these product are just hyper link which when clicked will take me to some third party website where the product details will be provide to the user where he can purchase the product.

    I have to send a SAML XML request to the Third party website.

    I have no idea on how to create SAML XML request and How to use SAML for Single sign on.

    I Need help on this.

    Thanks

    ReplyDelete
  5. Hi Stefan - Your createSAMLObject could be improved to just take a QName parameter, the classes passed to it all have the static DEFAULT_ELEMENT_NAME attribute that contains the same QName you retrieve in the function. Is there a reason you chose to use reflection instead?

    ReplyDelete
    Replies
    1. The reason is just simplicity and cleanliness when using the function.
      buildSAMLObject(Issuer.class) instead of
      buildSAMLObject(Issuer.DEFAULT_ELEMENT_NAME)

      I have not considered the performance effects of using reflections in this case. Any ideas on how much this affect performance?

      Delete