Wednesday, February 22, 2012

Reading metadata with OpenSAML

OpenSAML have several metods for reading and parsings SAML metadata.

Meta data is loaded using providers. For example

FilesystemMetadataProvider - Used to load data from a file on the filesystem
HTTPMetadataProvider - Used to load data from an Internet address

Here is an example on how to load meta data using the FilesystemMetadataProvider.
FilesystemMetadataProvider idpMetaDataProvider = new FilesystemMetadataProvider(new File("path to file"));
idpMetaDataProvider.setRequireValidMetadata(true);
idpMetaDataProvider.setParserPool(new BasicParserPool());
idpMetaDataProvider.initialize();
EntityDescriptor idpEntityDescriptor = idpMetaDataProvider.getEntityDescriptor("Some entity id");

The EntityDescriptor can then be used to extract data from the metadata. Here are some examples on how to use it.

SSO services
SingleSignOnService redirectEndpoint = null;
for (SingleSignOnService sss : idpEntityDescriptor.getIDPSSODescriptor(SAMLConstants.SAML20P_NS).getSingleSignOnServices()) {
   if (sss.getBinding().equals(SAMLConstants.SAML2_REDIRECT_BINDING_URI)) {
      redirectEndpoint = sss;
   }
}

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

The objects of OpenSAML metadata follows the structure of the metadata XML, so if you look at the XML it pretty easy to figure out how to read it with OpenSAML.

17 comments:

  1. Hey Stefan,

    Is there a way to check if an SP metadata is valid or not.... By valid I mean is the metadata following the correct syntax.... Thx in advance..

    ReplyDelete
    Replies
    1. I have not tried this, but i would think setting metadatafilter to http://www.imrantariq.com/saml/org/opensaml/saml2/metadata/provider/SchemaValidationFilter.html in the metadataprovider would do the trick. Could you give me feedback on this when you try it?

      Delete
  2. Hello Stefan. Do you have any idea how to use ChainingMetadataProvider?

    ReplyDelete
    Replies
    1. Seems pretty straight forward from what I read in the javadoc http://www.jarvana.com/jarvana/view/org/opensaml/opensaml/2.4.1/opensaml-2.4.1-javadoc.jar!/org/opensaml/saml2/metadata/provider/ChainingMetadataProvider.html

      You register a couple of providers, when you ask the provider for example a entity descriptor, the provider iterates over the providers and returns if any matches.

      Delete
  3. Hi Stefan,

    Thanks for your posts. I've been referencing a number of them as I work with OpenSAML.

    ReplyDelete
    Replies
    1. Thank you and reference away.
      My understanding is that OpenSAML is widely used and as there are alot of manual work invloved in uasge I imagine applications using this should have a verry special need.
      This makes curious so I try to ask people that visit my blog what they use it for.

      What do you use OpenSAML for?

      Delete
  4. Hi Stefan,

    I wanted to load in metadata as a string and had some luck with the DOMMetadataProvider:

    DocumentBuilderFactory documentBuilderFactory =
    DocumentBuilderFactory.newInstance();
    documentBuilderFactory.setNamespaceAware(true);
    DocumentBuilder db = documentBuilderFactory.newDocumentBuilder();
    InputSource is = new InputSource();
    is.setCharacterStream(new StringReader(metadata));
    Document doc = db.parse(is);
    Element metaElement = doc.getDocumentElement();
    logger.info("EntityID: " + metaElement.getAttribute("entityID"));
    DOMMetadataProvider idpMetaDataProvider = new DOMMetadataProvider(metaElement);
    idpMetaDataProvider.setRequireValidMetadata(true);
    idpMetaDataProvider.setParserPool(new BasicParserPool());
    idpMetaDataProvider.initialize();
    EntityDescriptor idpEntityDescriptor = idpMetaDataProvider.getEntityDescriptor(metaElement.getAttribute("entityID"));
    logger.info(idpEntityDescriptor.getID());

    ReplyDelete
  5. When i try to use your code i get:
    10:16:13,292 INFO ~ Next refresh cycle for metadata provider 'C:\metadata.xml' will occur on '2015-09-25T08:21:13.282Z' ('2015-09-25T10:21:13.282+02:00' local time)
    org.opensaml.saml2.metadata.provider.MetadataProviderException: Saw an error of type 'java.lang.NoClassDefFoundError' with message 'org/w3c/dom/ElementTraversal'
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.refresh(AbstractReloadingMetadataProvider.java:272)
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.doInitialization(AbstractReloadingMetadataProvider.java:239)
    at org.opensaml.saml2.metadata.provider.AbstractMetadataProvider.initialize(AbstractMetadataProvider.java:407)
    at controllers.ServiceProvider.metadataReader(ServiceProvider.java:177)
    at controllers.ServiceProvider.main(ServiceProvider.java:202)
    10:16:13,292 ERROR ~ Metadata provider failed to properly initialize, fail-fast=true, halting
    org.opensaml.saml2.metadata.provider.MetadataProviderException: Saw an error of type 'java.lang.NoClassDefFoundError' with message 'org/w3c/dom/ElementTraversal'
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.refresh(AbstractReloadingMetadataProvider.java:272)
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.doInitialization(AbstractReloadingMetadataProvider.java:239)
    at org.opensaml.saml2.metadata.provider.AbstractMetadataProvider.initialize(AbstractMetadataProvider.java:407)
    at controllers.ServiceProvider.metadataReader(ServiceProvider.java:177)
    at controllers.ServiceProvider.main(ServiceProvider.java:202)

    The code is extacly the same, java 1.6

    ReplyDelete
  6. Hi
    Do you have an example for readin metadata with OpenSaml 3 ? thanks

    ReplyDelete
    Replies
    1. I do not, but I'll put it on the todolist

      Delete
    2. Cool! Tried your book, but it said that it was out of the its scope.

      Delete
    3. Hi Stefan,

      Any luck with reading metadata with OpenSAML3 ? I am migrating a project from OpenSAML 2 to OpenSAML 3. Any pointers will be great.

      Delete
    4. Hi Stefan,

      Any luck with reading metadata with OpenSAML3 ? I am migrating a project from OpenSAML 2 to OpenSAML 3. Any pointers will be great.

      Delete
    5. FilesystemMetadataResolver / DOMMetadataResolver is the name

      Delete
  7. Hi Stefan,

    I'm getting below error when I try to read metadata file using FilesystemMetadataProvider.

    "org.opensaml.saml2.metadata.provider.MetadataProviderException: Unable to unmarshall metadata
    org.opensaml.saml2.metadata.provider.MetadataProviderException: org.opensaml.saml2.metadata.provider.MetadataProviderException: Unable to unmarshall metadata
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.refresh(AbstractReloadingMetadataProvider.java:270)
    at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.doInitialization(AbstractReloadingMetadataProvider.java:239)
    at org.opensaml.saml2.metadata.provider.AbstractMetadataProvider.initialize(AbstractMetadataProvider.java:407)"

    Below is the snippet,

    FilesystemMetadataProvider idpMetaDataProvider = new FilesystemMetadataProvider(new File("D:\metadata.xml"));
    idpMetaDataProvider.setRequireValidMetadata(true);
    idpMetaDataProvider.setParserPool(new BasicParserPool());
    idpMetaDataProvider.initialize();

    Thanks in advance.

    Regards,
    Ramesh Kumar G.

    ReplyDelete
    Replies
    1. Hi, if you're still having trouble, can you please post the metadatafile in a gist and I will give it a try

      Delete
    2. The backslash will escpae the m in D:\metadata

      Delete