Generating metadata with OpenSAML

OpenSAML can be used to generate metadata. As with reading metadata, the library is pretty straight forward in relation to the metadata XML.

This is an example for generating a SP metadata file

We start by creating the EntityDescriptor, setting the EntityId and building the SSO descriptor.

1EntityDescriptor spEntityDescriptor = SAMLUtil.buildSAMLObjectWithDefaultName(EntityDescriptor.class);
2spEntityDescriptor.setEntityID(entityID);
3SPSSODescriptor spSSODescriptor = SAMLUtil.buildSAMLObjectWithDefaultName(SPSSODescriptor.class);

In the SSO descriptor we request how we want the communication signed and encrypted

1spSSODescriptor.setWantAssertionsSigned(true); spSSODescriptor.setAuthnRequestsSigned(true);

And what certificates we want to use

 1X509KeyInfoGeneratorFactory keyInfoGeneratorFactory = new X509KeyInfoGeneratorFactory();
 2keyInfoGeneratorFactory.setEmitEntityCertificate(true);
 3KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance();
 4 
 5   
 6KeyDescriptor encKeyDescriptor = SAMLUtil.buildSAMLObjectWithDefaultName(KeyDescriptor.class);
 7 
 8encKeyDescriptor.setUse(UsageType.ENCRYPTION); //Set usage
 9 
10// Generating key info. The element will contain the public key. The key is used to by the IDP to encrypt data
11try {
12 encKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(X509Credential));
13} catch (SecurityException e) {
14 log.error(e.getMessage(), e);
15}
16 
17spSSODescriptor.getKeyDescriptors().add(encKeyDescriptor);
18   
19KeyDescriptor signKeyDescriptor = SAMLUtil.buildSAMLObjectWithDefaultName(KeyDescriptor.class);
20 
21signKeyDescriptor.setUse(UsageType.SIGNING);  //Set usage
22 
23// Generating key info. The element will contain the public key. The key is used to by the IDP to verify signatures
24try {
25 signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(X509Credential));
26} catch (SecurityException e) {
27 log.error(e.getMessage(), e);
28}
29 
30spSSODescriptor.getKeyDescriptors().add(signKeyDescriptor);

The keyInfoGenerator uses a X509Credential to generate the key info object with the public key.

Setting what type of pseudonym federation we want with the IDP.

1// Request transient pseudonym
2NameIDFormat nameIDFormat = SAMLUtil.buildSAMLObjectWithDefaultName(NameIDFormat.class);
3nameIDFormat.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:transient");
4spSSODescriptor.getNameIDFormats().add(nameIDFormat);

Setting location of services

1AssertionConsumerService assertionConsumerService = SAMLUtil.buildSAMLObjectWithDefaultName(AssertionConsumerService.class);
2assertionConsumerService.setIndex(0);
3assertionConsumerService.setBinding(SAMLConstants.SAML2_ARTIFACT_BINDING_URI);
4 
5// Setting address for our AssertionConsumerService
6assertionConsumerService.setLocation(assertionConsumerServiceURL);
7spSSODescriptor.getAssertionConsumerServices().add(assertionConsumerService);

And finally we set SAML as supported protocol and generate the XML

 1spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS);
 2 
 3spEntityDescriptor.getRoleDescriptors().add(spSSODescriptor);
 4 
 5DocumentBuilder builder;
 6DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 7 
 8builder = factory.newDocumentBuilder();
 9Document document = builder.newDocument();
10Marshaller out = Configuration.getMarshallerFactory().getMarshaller(spEntityDescriptor);
11out.marshall(spEntityDescriptor, document);
12 
13Transformer transformer = TransformerFactory.newInstance().newTransformer();
14StringWriter stringWriter = new StringWriter();
15StreamResult streamResult = new StreamResult(stringWriter);
16DOMSource source = new DOMSource(document);
17transformer.transform(source, streamResult);
18stringWriter.close();
19String metadataXML = stringWriter.toString();