Java SAML2 + simplesamlphp

The use case is as follows: the java application (SP) must use simplesamlphp as an IdP. I tested 2 libraries, these are the required configs.

SimpleSAMLphp

Please note that the default install from ubuntu (16.04.2) of simplesamlphp (14.0) does not work with the php version installed (php7) because of this bug so I ended installing everything from the tar.gz provided (14.14).

Onelogin

This is the first library I tested. To install it:

  • install maven, requires recent version, does not work with 3.0.5
  • export MAVEN_HOME=/usr/local/java/apache-maven-3.5.0
  • export PATH=$MAVEN_HOME/bin:$PATH
  • git clone https://github.com/onelogin/java-saml
  • cd java-saml
  • mvn package
  • download tomcat 7.0.78
  • install java-saml-toolkit-jspsample as a expanded war in this tomcat
  • tweaked the files: onelogin.saml.properties and the simplesamlphp config until it worked. The key is to use the information from the IdP metadata (http://idp-domain/simplesamlphp/saml2/idp/metadata.php?output=xhtml) and transpose it in the properties file.

Pac4j

This is a more complex library. There is also a demo application for j2e.

To clone, compile and run this demo the sequence is straight forward:

  • git clone https://github.com/pac4j/j2e-pac4j-demo
  • cd j2e-pac4j-demo
  • mvn package
  • mvn jetty:run

The test with https://www.testshib.org works.

To configure if for simpleSAMLphp. Modify DemoConfigFactory.java

final SAML2ClientConfiguration cfg = new SAML2ClientConfiguration("resource:samlKeystore.jks",
 "pac4j-demo-passwd",
 "pac4j-demo-passwd",
 "resource:idp-metadata.xml");
 cfg.setMaximumAuthenticationLifetime(3600);
 cfg.setServiceProviderEntityId("test.pac4j");
 cfg.setServiceProviderMetadataPath(new File("sp-metadata.xml").getAbsolutePath());
 final SAML2Client saml2Client = new SAML2Client(cfg);

The idp-metadata.xml file is the file from: http://idp-domain/simplesamlphp/saml2/idp/metadata.php?output=xhtml wrapped in an additional EntitiesDescriptors element:

<md:EntitiesDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> 
 <md:EntityDescriptor entityID="http://idp-domain/simplesamlphp/saml2/idp/metadata.php">

However at this point the application gives a “fatal error”:

org.pac4j.saml.exceptions.SAMLException: Identity provider has no single sign on service available for the selected profileorg.opensaml.saml.saml2.metadata.impl.IDPSSODescriptorImpl@2d6719d3

The error seems to be here https://github.com/pac4j/pac4j/blob/master/pac4j-saml/src/main/java/org/pac4j/saml/context/SAML2MessageContext.java#L104 so I am left with no clue to the problem. The only solution is to change a bit the code to see which is the binding required.

Just cloning the main repository and trying to compile it with maven does not work. The error is:

[INFO] Scanning for projects...
[ERROR] [ERROR] Some problems were encountered while processing the POMs:
[FATAL] Non-resolvable parent POM for org.pac4j:pac4j-couch:[unknown-version]: Could not find artifact org.pac4j:pac4j:pom:2.0.0-RC3-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 5, column 10
@ 
[ERROR] The build could not read 1 project -> [Help 1]
[ERROR] 
[ERROR] The project org.pac4j:pac4j-couch:[unknown-version] (/phantom/java/pac4j/pac4j-couch/pom.xml) has 1 error
[ERROR] Non-resolvable parent POM for org.pac4j:pac4j-couch:[unknown-version]: Could not find artifact org.pac4j:pac4j:pom:2.0.0-RC3-SNAPSHOT and 'parent.relativePath' points at wrong local POM @ line 5, column 10 -> [Help 2]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/ProjectBuildingException
[ERROR] [Help 2] http://cwiki.apache.org/confluence/display/MAVEN/UnresolvableModelException

The solution is to checkout the 2.0.0 tag:

  • git clone https://github.com/pac4j/pac4j
  • git tag -l
  • git checkout tags/pac4j-2.0.0

At this point I change the code to give the name of the binding:

org.pac4j.saml.exceptions.SAMLException: Identity provider has no single sign on service available for the selected profileurn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST

The solution is to modify the metadata/saml20-idp-hosted.php file and add:

'SingleSignOnServiceBinding' => array('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'),
'SingleLogoutServiceBinding' => array('urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect', 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'),

This will generate the

<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"

in the metadata which generated this error.

At this point the SSO works. Of course the entityID for the SP must be configured in metadata/saml20-sp-remote.php

$metadata['diapason.test.pac4j'] = array(
 'AssertionConsumerService' => 'http://localhost:8080/callback?client_name=SAML2Client',

Leave a Reply

*