OpenSAML authentication with Webtop 16.7.9

If you’re using SAML authentication with Webtop and you upgrade to 16.7.9 you’ll experience some issues (=it doesn’t work) if you need to sign the request to your IdP. Why is this happening?

In latest Webtop version Opentext has upgraded the bundled opensaml libraries from version 2 (released on 2011, support stopped on 2018) to version 4. In this many years that have passed since version 2 was released, the way the connection is done has been completely changed.

However, in this case OT engineering team properly updated the code that handles the request to the IdP. Unluckily, they didn’t do the same with the code that signs the request :/

Checking the code, you can see really weird castings between same types on the getServiceProviderSignature method:

       X509Certificate certificate = (X509Certificate)privateKeyEntry.getCertificate();
        BasicX509Credential credential = new BasicX509Credential();
        credential.setEntityCertificate(certificate);
        credential.setPrivateKey(privateKey);
        signature = (Signature)Configuration.getBuilderFactory().getBuilder(Signature.DEFAULT_ELEMENT_NAME).buildObject(Signature.DEFAULT_ELEMENT_NAME);
        signature.setSigningCredential((Credential)credential);

From this code, we can tell that OT was able to properly follow the instructions on how to send a request to the IdP (https://blog.samlsecurity.com/2011/01/redirect-with-authnrequest.html) but they were not so diligent with the signature process (https://blog.samlsecurity.com/2012/11/verifying-signatures-with-opensaml.html), so what they basically did was “force the code to compile”.

Well, if you bother to follow the opensaml blog post containing the instructions on how to sign a request with OpenSAML 4 you’ll get something like this new fancy getServiceProviderSignature method:

//getServiceProviderSignature compatible OpenSAML 4
private Credential getServiceProviderSignature() {
    BasicX509Credential credentialx509=null;
    if (StringUtil.isEmptyOrNull(this.m_serviceProviderJKS) || StringUtil.isEmptyOrNull(this.m_serviceProviderJKSPwd) ||
        StringUtil.isEmptyOrNull(this.m_serviceProviderJKSKeyEntryPwd) || StringUtil.isEmptyOrNull(this.m_serviceProviderJKSKeyEntryAlias)) {
        traceMsg("Keystore proeprties are not configured properly for SAML request signing. So returning the signature as nullConfigure keystore properties if signing is enabled in Webtop and IDP configurations.");
        return null;
    }
    try {
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        FileInputStream fileInputStream = new FileInputStream(new File(this.m_serviceProviderJKS));
        char[] jksPassword = this.m_serviceProviderJKSPwd.toCharArray();
        char[] jksEntryKeyPassword = this.m_serviceProviderJKSKeyEntryPwd.toCharArray();
        keyStore.load(fileInputStream, jksPassword);
        fileInputStream.close();

        KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(this.m_serviceProviderJKSKeyEntryAlias, new KeyStore.PasswordProtection(jksEntryKeyPassword));
        PrivateKey privateKey = privateKeyEntry.getPrivateKey();
        X509Certificate certificate = (X509Certificate)privateKeyEntry.getCertificate();
        credentialx509 = new BasicX509Credential(certificate, privateKey);

    } catch (Exception e) {
        Trace.println("Failed to get the signature to sign the SAML authentication request: " + e.getLocalizedMessage());
        throw new RuntimeException(e);
    }
    return credentialx509;
}

which should work perfectly (there are some additional modifications to other methods, but this should get you going).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.