1) Install and configure the Apache CXF Fediz IdP and sample Webapp
Firstly, follow a previous tutorial to deploy the latest Fediz IdP + STS to Apache Tomcat, as well as the "simpleWebapp". Test that the "simpleWebapp" is working correctly by navigating to the following URL (selecting "realm A" at the IdP, and authenticating as "alice/ecila"):
- https://localhost:8443/fedizhelloworld/secure/fedservlet
In the 'idp-realmA' bean:
- Change the port in "idpUrl" to "8443".
- Change the "url" value to "http://localhost:9080/idp/profile/SAML2/Redirect/SSO".
- Change the "protocol" value to "urn:oasis:names:tc:SAML:2.0:profiles:SSO:browser".
- Add the following property: <property name="parameters"><util:map><entry key="require.known.issuer" value="false" /></util:map></property>
2) Install and configure Shibboleth
This is a reasonable complex task, so let's break it down into various sections.
2.1) Install Shibboleth and deploy to Tomcat
Download and extract the latest Shibboleth Identity Provider (tested with 3.2.1). Install Shibboleth by running the "install.sh" script in the bin directory. Install Shibboleth to "$SHIB_HOME" and use the default values that are prompted as part of the installation process, entering a random password for the keystore (we won't be using it). Download and extract an Apache Tomcat 7 instance, and follow these steps:
- Copy '$SHIB_HOME/war/idp.war' into the Tomcat webapps directory.
- Configure Shibboleth to find the IDP by defining: export JAVA_OPTS="-Xmx512M -Didp.home=$SHIB_HOME".
- Next you need to download the jstl jar (https://repo1.maven.org/maven2/jstl/jstl/1.2/) + put it in the lib directory of Tomcat.
- Edit conf/server.xml + change the ports to avoid conflict with the Tomcat instance that the Fediz IdP is running in. (e.g. use 9080 instead of 8080, etc.).
- Now start Tomcat + check that everything is working by navigating to: http://localhost:9080/idp/profile/status
Next we need to configure the Fediz IdP as a RP (relying party) in Shibboleth. The Fediz IdP has the ability to generate metadata (either WS-Federation or SAML SSO) for a trusted IdP. Navigate to the following URL in a browser and save the metadata to a local file "fediz-metadata.xml":
- https://localhost:8443/fediz-idp/metadata/urn:org:apache:cxf:fediz:idp:realm-B
<MetadataProvider id="FedizMetadata" xsi:type="FilesystemMetadataProvider" metadataFile="$METADATA_PATH/fediz-metadata.xml"/>
As we won't be encrypting the SAML response in this demo, edit the '$SHIB_HOME/idp.properties' file and uncomment the "idp.encryption.optional = false" line, changing "false" to "true".
2.3) Configuring the Signing Keys in Shibboleth
Next we need to copy the keys that Fediz has defined for "realm B" to Shibboleth. Copy the signing certificate "realmb.cert" from the Fediz source and rename it as '$SHIB_HOME/credentials/idp-sigining.crt'. Next we need to extract the private key from the keystore and save it as a plaintext private key. Download the realmb keystore. Extract the private key via:
- keytool -importkeystore -srckeystore stsrealm_b.jks -destkeystore stsrealmb.p12 -deststoretype PKCS12 -srcalias realmb -deststorepass storepass -srcstorepass storepass -srckeypass realmb -destkeypass realmb
- openssl pkcs12 -in stsrealmb.p12 -nodes -nocerts -out idp-signing.key
- Edit idp-signing.key to remove any additional information before the "BEGIN PRIVATE KEY" part.
- cp idp-signing.key $SHIB_HOME/credentials
Next we need to configure Shibboleth to authenticate users. If you have a configured KDC or LDAP installation on your machine, then it is easiest to use this, if you configure some test users there. If not then, in this section we will configure Shibboleth to use JAAS to authenticate users via Kerberos. Edit '$SHIB_HOME/conf/authn/password-authn-config.xml' + comment out the ldap import, instead uncommenting the "jaas-authn-config.xml" import. Next edit '$SHIB_HOME/conf/authn/jaas.config' and replace the contents with:
ShibUserPassAuth {
com.sun.security.auth.module.Krb5LoginModule required refreshKrb5Config=true useKeyTab=false;
};
Now we will set up and configure a test KDC. Assuming you are running this demo on linux, edit '/etc/krb5.conf' and change the "default_realm" to "service.ws.apache.org" + add the following to the realms section:
service.ws.apache.org = {
kdc = localhost:12345
}
Now we will look at altering a test-case I wrote that uses Apache Kerby as a test-kdc. Clone my testcases github repo and go to the "cxf-kerberos-kerby" test-case, which is part of the top level "cxf" projects. Edit the AuthenticationTest
and change the values for KDC_PORT + KDC_UDP_PORT to "12345". Next remove the @org.junit.Ignore annotation from the "launchKDCTest()" method to just launch the KDC + sleep for a few minutes. Launch the test on the command line via "mvn test -Dtest=AuthenticationTest".
2.5) Configure Shibboleth to include the authenticated principal in the SAML Subject
For the purposes of our demo scenario, the Fediz IdP expects the authenticated principal in the SAML Subject it gets back from Shibboleth. Edit '$SHIB_HOME/conf/attribute-filter.xml' and add the following:
<AttributeFilterPolicy id="releasePersistentIdToAnyone">
<PolicyRequirementRule xsi:type="ANY"/>
<AttributeRule attributeID="persistentId">
<PermitValueRule xsi:type="ANY"/>
</AttributeRule>
</AttributeFilterPolicy>
Edit '$SHIB_HOME/conf/attribute-resolver.xml' and add the following:
<resolver:AttributeDefinition id="persistentId" xsi:type="ad:PrincipalName">
<resolver:AttributeEncoder xsi:type="enc:SAML1StringNameIdentifier" nameFormat="urn:mace:shibboleth:1.0:nameIdentifier"/>
<resolver:AttributeEncoder xsi:type="enc:SAML2StringNameID" nameFormat="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent"/>
</resolver:AttributeDefinition>
Edit '$SHIB_HOME/conf/saml-nameid.xml' and comment out any beans listed in the "shibboleth.SAML2NameIDGenerators" list. Finally, edit '$SHIB_HOME/conf/saml-nameid.properties' and uncomment the legacy Generator:
idp.nameid.saml2.legacyGenerator = shibboleth.LegacySAML2NameIDGenerator
That will enable Shibboleth to process the "persistent" attribute using the Principal Name. (Re)start the Tomcat instance we we should be ready to go.
3) Testing the service
To test the service navigate to:
- https://localhost:8443/fedizhelloworld/secure/fedservlet