This is an example for generating a SP metadata file
We start by creating the EntityDescriptor, setting the EntityId and building the SSO descriptor.
EntityDescriptor spEntityDescriptor = SAMLUtil.buildSAMLObjectWithDefaultName(EntityDescriptor.class); spEntityDescriptor.setEntityID(entityID); SPSSODescriptor spSSODescriptor = SAMLUtil.buildSAMLObjectWithDefaultName(SPSSODescriptor.class);
In the SSO descriptor we request how we want the communication signed and encrypted
spSSODescriptor.setWantAssertionsSigned(true); spSSODescriptor.setAuthnRequestsSigned(true);
And what certificates we want to use
X509KeyInfoGeneratorFactory keyInfoGeneratorFactory = new X509KeyInfoGeneratorFactory(); keyInfoGeneratorFactory.setEmitEntityCertificate(true); KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance(); KeyDescriptor encKeyDescriptor = SAMLUtil.buildSAMLObjectWithDefaultName(KeyDescriptor.class); encKeyDescriptor.setUse(UsageType.ENCRYPTION); //Set usage // Generating key info. The element will contain the public key. The key is used to by the IDP to encrypt data try { encKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(X509Credential)); } catch (SecurityException e) { log.error(e.getMessage(), e); } spSSODescriptor.getKeyDescriptors().add(encKeyDescriptor); KeyDescriptor signKeyDescriptor = SAMLUtil.buildSAMLObjectWithDefaultName(KeyDescriptor.class); signKeyDescriptor.setUse(UsageType.SIGNING); //Set usage // Generating key info. The element will contain the public key. The key is used to by the IDP to verify signatures try { signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(X509Credential)); } catch (SecurityException e) { log.error(e.getMessage(), e); } spSSODescriptor.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.
// Request transient pseudonym NameIDFormat nameIDFormat = SAMLUtil.buildSAMLObjectWithDefaultName(NameIDFormat.class); nameIDFormat.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:transient"); spSSODescriptor.getNameIDFormats().add(nameIDFormat);
Setting location of services
AssertionConsumerService assertionConsumerService = SAMLUtil.buildSAMLObjectWithDefaultName(AssertionConsumerService.class); assertionConsumerService.setIndex(0); assertionConsumerService.setBinding(SAMLConstants.SAML2_ARTIFACT_BINDING_URI); // Setting address for our AssertionConsumerService assertionConsumerService.setLocation(assertionConsumerServiceURL); spSSODescriptor.getAssertionConsumerServices().add(assertionConsumerService);
And finally we set SAML as supported protocol and generate the XML
spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); spEntityDescriptor.getRoleDescriptors().add(spSSODescriptor); DocumentBuilder builder; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); Marshaller out = Configuration.getMarshallerFactory().getMarshaller(spEntityDescriptor); out.marshall(spEntityDescriptor, document); Transformer transformer = TransformerFactory.newInstance().newTransformer(); StringWriter stringWriter = new StringWriter(); StreamResult streamResult = new StreamResult(stringWriter); DOMSource source = new DOMSource(document); transformer.transform(source, streamResult); stringWriter.close(); String metadataXML = stringWriter.toString();
Hi,
ReplyDeleteThanks so much for this example. Would it be possible to obtain the source code for SAMLUtil?
Thanks,
Rachel Struthers
I think this is what you want http://mylifewithjava.blogspot.no/2011/04/convenience-methods-for-opensaml.html
ReplyDeleteHi,
ReplyDeleteVery neat series of examples for OpenSAML. Very much appreciated.
What is the difference between uildSAMLObjectWithDefaultName and buildXMLObjectDefaultName? I have had a look at the convenience method link that you have provided, but could not figure out the difference and the necessity between them. It would be very helpful to have any suggestion.
Thanks,
Ripul
There is no differance, it should be buildSAMLObjectWithDefaultName. I have now changes this in all posts affected
DeleteThis comment has been removed by the author.
ReplyDeleteHi Stefan,
ReplyDeleteMany thanks for your reply. I have been able to generating SP Metadata with your examples, but struggling to find a way to generate IdP Metadata. Any suggestion would be highly appreciated.
Ripul
I have never tried that, but it shouldn't be very much different from SP metadata. I would suggest finding an example IDP metadata file and try to recreate it with OpenSAML. Many of the XML elements in the metadata are represented by OpenSAML classes with the same name. What exactly are you struggling with?
DeleteMany thanks for your reply.
DeleteActually, I have been able to generate the metadata. I am struggling with signing the metadata. I have looked into some examples for signing a SAML Assertion, but a bit lost for signing metadata. Any help would be highly appreciated.
Ripul
Hi,
DeleteI have managed to resolve all problems. I did not know EntityDescriptor has a setSignature method. It solved all the problems :). I would be totally lost without your helpful tutorials since OpenSAML documentation is close to nothing. Many thanks for that.
Yes that is the one to use. How do you generate the signatures? I will soon come out with a post on how to sign elements. It's on my todo list. Yes OpenSAML is not very well documented.
DeleteI used the tutorial from the following location which shows how to sign a SAML Assertion:
Deletehttp://narendrakadali.wordpress.com/2011/06/05/sign-assertion-using-opensaml/
I had problems since I was not aware that the EntityDescriptor had setSignature method. So initially, I used the common XML Signing method which was very lengthy. Once I came to know about the setSignature method the code was neat and was just trivial.
Many thanks.
This comment has been removed by the author.
ReplyDeleteThank you so much for this article. My onlu question is when you say keyInfoGenerator.generate(X509Credential),how do you generate this X509Credential? Do you buy a certificate from some CA?
ReplyDeleteany pointers for creating X509 Credential for a SP?
ReplyDeleteUsually you don't buy a certificate from a CA for this purpose. You can generate one with OpenSSL.
Deletethank you so much.
Deletehow to generate the certificate from openSSL . I know we can generate it with a private key .
ReplyDelete1)I want to knw how to provide the issuing entity ID/alias ?
2)And are the keystore password and keystore private key password same if different how to generate them also with the certificate
try using keytool http://www.dotkam.com/2008/04/22/creating-public-and-private-certificateskeys/
Deletethanks for the link . Could you provide me link or tutorial of how to configure the generate certificate/keystore to the CredentialResolver in opensaml . I want to implement my own class by extending that inferface CredentialResolver.
DeleteI'm not sure what you want but I think you whant to use the keystore in the link as a credential in OpenSAML. In that case I have everything you need. http://mylifewithjava.blogspot.no/2011/03/getting-credentials-in-opensaml.html
DeleteOk. Let me explain you my problem. Currently the saml is using a JKS implemention for signing the saml assertion . its using basically a Base64 encoded value as the keystore and has a public and private keys . So we are using the opensaml KeyStoreCredentialResolver class for it to get the resolver. Now the problem is I want change the keystore from the JKS to openssl. Thank you for the link above but its also using the keyStoreCredentialsResolver to generate the credential. I cannot use it as it will expect the entityID as a parameter in password MAP . PLease HELP!!!
DeleteChange to openssl? What are you generating with openssl? p12? Why do you change?
DeleteYes I need to modify the code FROM JKS to use a openssl pkcs8 file. And I generate a .PEM and then to use it with java I generate a PKCS8 file using openssl .
DeleteHeres a code that i using to generate teh signing credentials :
RandomAccessFile rafObj = new RandomAccessFile("D:\\saml_certifications\\sample.pkcs8", "r");
byte[] buf = new byte[(int)rafObj.length()];
rafObj.readFully(buf);
rafObj.close();
PKCS8EncodedKeySpec kspec = new PKCS8EncodedKeySpec(buf);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privKey = kf.generatePrivate(kspec);
credential = new BasicX509Credential();
credential.setUsageType(UsageType.SIGNING);
credential.setPrivateKey(privKey);
return credential
with the code above i am able to sign the but it failing to set the public key .
How about this then, I found some code in stackoverflow, http://stackoverflow.com/questions/2654949/how-to-read-a-password-encrypted-key-with-java
DeleteKeyFactory rsaKeyFac = KeyFactory.getInstance("RSA");
// First get the private key
RSAPrivateCrtKey rsaPriv = (RSAPrivateCrtKey) rsaKeyFac.generatePrivate(pkcs8KeySpec);
// Now derive the RSA public key from the private key
RSAPublicKeySpec rsaPubKeySpec = new RSAPublicKeySpec(rsaPriv.getModulus(), rsaPriv.getPublicExponent());
RSAPublicKey rsaPubKey = (RSAPublicKey) rsaKeyFac.generatePublic(rsaPubKeySpec);
credential = new BasicX509Credential();
credential.setUsageType(UsageType.SIGNING);
credential.setPrivateKey(rsaPriv);
credential.setPublicKey(rsaPubKey);
return credential
hey stefan, It works great !!! but the generate AuthnRequest xml is missing the attribute . how can i add it.
DeleteWhat attribute?
DeleteThis comment has been removed by the author.
Deletesorry my mistake i was referrring to KeyInfo with x506Certificate. I really didnt want to put all that code here in comment and spoil article. So i created a issue in StackOverflow :
Deletehttp://stackoverflow.com/questions/16399945/how-to-sign-an-saml-2-0-assertion-using-the-openssl-pcks8-file
Please check it .
Good call, I will have a look tomorrow
DeleteOK alright.
DeleteI have generated signed SAML1.1 response using keystore. Now I got the metadata from SP, how to use this metadata in my Java code. Please help me ...
ReplyDeleteWe have to configure it on my local server or we have to write code for this. what is use of this metadata please suggest.
I am trying to use Generating metadata with OpenSAML to generate metadata to a given entity Id..Is it possible to share a code base for SAMLUtil class to me?
ReplyDeleteYou can find the methods here, http://mylifewithjava.blogspot.no/2011/04/convenience-methods-for-opensaml.html
Deletehey Stefan, could the above be simplified more ?
ReplyDeleteKeyDescriptor signKeyDescriptor =SAMLUtil.buildSAMLObjectWithDefaultName(KeyDescriptor.class);
signKeyDescriptor.setUse(UsageType.SIGNING);
X509Certificate x509Certificate = null;
KeyInfo keyinfo = SAMLUtil.buildSAMLObjectWithDefaultName(KeyInfo.class);
KeyInfoHelper.addCertificate(keyInfo, x509Certificate);
signKeyDescriptor.setKeyInfo(keyInfo);
Interesting, I will have to try that
DeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHi Stefen,
ReplyDeleteI'm completely new to SAML2.0. I got a requirement to implement SP for one of our company product. I bought your book and is really helpful. I'm still confused with few questions. Can you please clarify my questions?
I'm trying out service provider implementation on my local. Let us assume I have SP metadata that has my localhost url references for assertion consumer service.
1. How can I test sso login with some test IdP account that runs on
https?
2. Do I need to exchange my localhost SP metadata with IdP? Can I
do that at all? Is that recommended?
3. How can I test OpenSAML implementation end to end in http
environment even if the IdP runs on https?
Basically I have to make sure sso work as expected before I move to development and then to production. Also our development environment does not run on https. I am really confused when it comes to testing part.
Just for clarification, I have no control on IdP side. All I can request from IdP side is their metadata (both test and prod accounts).
DeleteTo test you basically configure the SP and the IDP with each others metadata and then start a authentication from the SP. How this is done depends on the IDP.
DeleteYes you typically exchange the metadata with the IDP.
If the IDP only accepts https and you con not control it then you will need use https for the IDP endpoints. However you can of course use http for you endpoints.