My aim is to implement the Single Log Out Protocol. First I am understanding how the standar works and how I can fit it in my scenario: ADFS 2.0 as IdP, for me is like a "black box"
What I am doing at the moment is the next:
Send an <AuthnRequest>
to my IdP
IdP asks me for credentials, I provide them and get succesfully login.
Get the SessionIndex value form the and constructs a <LogoutRequest>
<samlp:LogoutRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_135ad2fd-b275-4428-b5d6-3ac3361c3a7f" Version="2.0" Destination="https://idphost/adfs/ls/" IssueInstant="2008-06-03T12:59:57Z"><saml:Issuer>myhost</saml:Issuer><NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" NameQualifier="https://idphost/adfs/ls/">[email protected]</NameID<samlp:SessionIndex>_0628125f-7f95-42cc-ad8e-fde86ae90bbe</samlp:SessionIndex></samlp:LogoutRequest>
Take the above <LogoutRequest>
and encode it in Base64
Contructs the next string: SAMLRequest=base64encodedRequest&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1
With the above string generates the signature
Encode the signature in base64
Send the request: https://"https://idphost/adfs/ls/?SAMLRequest=base64encodedRequest&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1&Signature=base64EncodedSignature
But the IdP is answering me: The verification of the SAML message signature failed.
For signing I am using my private key (2048 bytes), and for verifying it is supposed that the IdP is using my public key (the one that I sent it when I registered my host)
The code for signing the request looks like:
// Retrieve the private key
KeyStore keyStore = KeyStore.getInstance("JKS", "SUN");
FileInputStream stream;
stream = new FileInputStream("/path/to/my/keystore.jks");
keyStore.load(stream, "storepass".toCharArray());
PrivateKey key = (PrivateKey) keyStore.getKey("keyAlias","keyPass".toCharArray());
// Create the signature
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(key);
signature.update("SAMLRequest=jVJda8IwFH2e4H8ofW%2BbVmvboGWCDApusDn2sBdJm1sNtEmXmw7x1y92KDrY2Ov5uueEzJG1TUfXaqd68wIfPaBxDm0jkQ7Mwu21pIqhQCpZC0hNRTfLxzWNfEI7rYyqVONeWf52METQRijpOsVq4W7JoSzjJJnWAEAmwLMMpmRG0jCrYJICIcR13kCjdSxcG%2BA6K9tQSGYGZG9MhzQIGrUT0uPw6VegpV%2FtA8ZrDBq0ZxB7KCQaJo2NICT1yMwjk9cwonFG4%2BTdzceju%2FmpOx3EOu8qYThgGJ3j5sE1fZE%2F2X3FynlQumXm9%2BGhHw6I4F49SCm0TDRLzjWgrXiKee5ZI2oB%2Bj%2Bj8qYX6GvFtdj1cPRryzPJ4Xh%2F2%2Fe736VvRzf2nn24wmoP%2BZbMojSM4tpL6iz2plFVeYyn4NUc0hmDjJQlfCf9cI5HZ%2Fjm4%2BRf&RelayState=null&SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1".getBytes());
String signatureBase64encodedString = (new BASE64Encoder()).encodeBuffer(signature.sign());
A SAML logout request follows your typical SAML message structure, with an ID, lifetime data, and information about its origin and destination. However, it also includes the name ID of the user who is being logged out. This allows the IdP or SP to confirm that they are logging out the correct user.
Single Logout (SLO) is a feature in federated authentication where end users can sign out of both their Okta session and a configured application with a single action. Okta supports this sign out process only when initiated by a Service Provider (SP). The SP sends the SLO request to Okta to end the Okta session.
Finally I got the right recipe:
We can perform the steps 2 and 3 with the SAML 2.0 Debugger (https://rnd.feide.no/simplesaml/module.php/saml2debug/debug.php). And for the URL-encoding use the classic w3schools (http://www.w3schools.com/tags/ref_urlencode.asp)
Warning! Ensure that the algorithm for your relying party, in the ADFS2, is setup to SHA1!
Best regards,
Luis
ps: now I have to code a little bit...
pps: You can find the code here: https://github.com/cerndb/wls-cern-sso/tree/master/saml2slo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With