SAML update, assertion and redirect issues

12
Recently we updated the SAML module on our application and we are getting some weird issues. The module used to work perfectly fine. We are running Mendix 8.18.6, and SAML module version 2.1.3. The request to our SAML provider is successful, and the response comes back successfully. The interface shows that we have both a request and response, and the response status says successful in the XML. However, the Principal on the SAML request entity is not getting filled out when the request comes back. The SAML providers redirection back to {APPURL}/SSO/assertion also fails with a 500 error. The error log with this message, “Unable to validate Response, see SAMLRequest overview for detailed response. Error: null” and it has this stack trace (I have shortened it for length reasons) java.lang.NullPointerException: null at saml20.implementation.ArtifactHandler.handleSAMLResponse(ArtifactHandler.java:76) at saml20.implementation.ArtifactHandler.handleRequest(ArtifactHandler.java:49) at saml20.implementation.SAMLRequestHandler.processRequest(SAMLRequestHandler.java:165) at com.mendix.externalinterface.connector.RequestHandler.doProcessRequest(RequestHandler.java:46) at com.mendix.external.connector.MxRuntimeConnector$1.execute(MxRuntimeConnector.java:76) at com.mendix.external.connector.MxRuntimeConnector$1.execute(MxRuntimeConnector.java:73) We also get this error log, “Unable to render error template” with this stack trace (also shortened) org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource '/SAML/templates/saml2-error-result.vm' at org.apache.velocity.runtime.resource.ResourceManagerImpl.loadResource(ResourceManagerImpl.java:474) at org.apache.velocity.runtime.resource.ResourceManagerImpl.getResource(ResourceManagerImpl.java:352) at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533) at org.apache.velocity.app.VelocityEngine.mergeTemplate(VelocityEngine.java:343) at saml20.implementation.SAMLRequestHandler.handleError(SAMLRequestHandler.java:223) at saml20.implementation.SAMLRequestHandler.processRequest(SAMLRequestHandler.java:167) at com.mendix.externalinterface.connector.RequestHandler.doProcessRequest(RequestHandler.java:46) at com.mendix.external.connector.MxRuntimeConnector$1.execute(MxRuntimeConnector.java:76) at com.mendix.external.connector.MxRuntimeConnector$1.execute(MxRuntimeConnector.java:73) Any help appreciated. Thanks
asked
6 answers
5

As PM who is responsible for the SAML module, I would like to add some clarification for the SAML module.

 

Mendix will be releasing new versions of the SAML module for both Mendix 7 and Mendix 8. These are planned to include the following fixes:

  • Null pointer exception when using the SAML module with Azure AD
  • Upgrades of various libraries to the latest.

These releases (2.1.4 and 1.15.4) are scheduled for end of June.

Furthermore, Mendix will be releasing a version for Mendix 9 that will be equivalent to v2.1.4 and 1.15.4 and which will also be using Atlas 3.0.
Mendix expects this release will be done in July.

 

Mendix was aware of the limitation with Azure AD in the recent versions and decided to release those so customers who are not using Azure AD would benefit from the improvements that were done. Mendix failed to include the known limitation for Azure AD in the release notes on the MarketPlace and will be updating those release notes.

(The dates mentioned here are target-dates and these dates could slip if unforseen circumstances would occur)

answered
9

I have found a workaround, however I don’t know if this is even a secure fix. I know the most recent updates fixed some vulnerabilities, so I want to make sure that there is a permanent secure fix in place. If anyone has any info on this let me know.
My fix was this. Line 203 in the MxSAMLResponse.java file was just returning the result of this method “MxSAMLEncryptedAssertion.decryptAssertion(this.response, credential, true);” in our case this method was returning null meaning the assertion was always null. To fix this I check to see if the result is null before returning. If it is null then the “MxSAMLAssertion.fromResponse(this.response);” method runs, which actually returns the assertion.

public MxSAMLAssertion getAssertion(Credential credential) throws SAMLException {
    // return the
    if (this.assertion != null) {
        return this.assertion;
    }

    if (credential != null) {
    	//return MxSAMLEncryptedAssertion.decryptAssertion(this.response, credential, true); This was the original line. This was replaced with the next four lines to fix issues with null assertions
    	MxSAMLAssertion assertionResult = MxSAMLEncryptedAssertion.decryptAssertion(this.response, credential, true);
    	if(assertionResult != null) {
    		return assertionResult;
    	}
    }

    return MxSAMLAssertion.fromResponse(this.response);
}

 

answered
3

Regarding the “Unable to render error template” error, here’s what makes the error messages work again for me.

Please note that I did not test any other parts of the SAML module where velocity templates are used such as in binding/PostBindingHandler.java and implementation/DiscoveryHandler.java

--- saml20\implementation\common\HTTPUtils.java
+++ saml20\implementation\common\HTTPUtils.java
@@ -28,17 +28,16 @@
     protected static final ILogNode _logNode = Core.getLogger(Constants.LOGNODE);
 
     public static VelocityEngine getEngine() {
         VelocityEngine engine = new VelocityEngine();
         Properties p = new Properties();
         // FIXME: how to make velocity read our custom templates
-//        final String templateDir = Core.getConfiguration().getResourcesPath().getAbsolutePath() + File.separator + "SAML" + File.separator;
-//        _logNode.info("Velocity template dir " + templateDir);
-//        p.setProperty("file.resource.loader.path", templateDir);
-        p.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
-        p.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
+        final String templateDir = Core.getConfiguration().getResourcesPath().getAbsolutePath() + File.separator + "SAML" + File.separator;
+        _logNode.info("Velocity template dir " + templateDir);
+        p.setProperty("file.resource.loader.path", templateDir);
+        p.setProperty("resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
         p.setProperty("runtime.log", Core.getConfiguration().getTempPath().getAbsolutePath() + File.separator + "velocity.log");
         engine.init(p);
 
         return engine;
     }
 
--- saml20\implementation\SAMLRequestHandler.java   
+++ saml20\implementation\SAMLRequestHandler.java   
@@ -217,13 +217,13 @@
         response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
 
         try {
             Writer writer = response.getWriter();
             // this.engine.mergeTemplate("templates/saml2-http-ui-response.vm", "UTF-8", ctx, writer);
             // FIXME: template location
-            this.engine.mergeTemplate("/SAML/templates/saml2-error-result.vm", "UTF-8", ctx, writer);
+            this.engine.mergeTemplate("templates/saml2-error-result.vm", "UTF-8", ctx, writer);
             writer.flush();
         } catch (Exception e1) {
             _logNode.error("Unable to render error template", e1);
         }
     }
 }

 

answered
2

Thanks for sharing your workaround. I contacted Mendix support about this. They replied with a workaround, but I never got it working with that one. While I await their official and final solution I decided to try yours, and everything is working fine again over here. I also don’t see any strange changes you made, so I wouldn’t expect this to be harmful. Will edit this post as soon as I have a final working solution from Mendix Support.

This was their initial workaround:

Hi Dennis,

Thank you for confirming! I would like to share with you that this is a known issue with our SAML module. Our team is currently working on a fix. 

As a workaround, can you please add 
        if (inResponseTo == null) {
            return null;
        }
in the retrieveCorrespondingRequest method in SAMLUtil.java?

 

answered
2

Thanks for sharing. I do wonder how this got by the quality tests of Mendix. I also created a ticket for this module to document the jar files that are no longer needed. Because they did change a lot in this release and if you are not carefull you end up with a lot of jar files that are no longer needed in your userlib.

Regards,

Ronald

 

answered
1

Regarding “Unable to render error template””

It appears that 2.1.3 configures Velocity to look for the templates in the classpath rather than the file system (HTTPUtils.java, method getEngine() ) , and reverting that back to the previous behavior and adjusting the template path in SAMLRequestHandler.java makes error messages work again. 

However since that module has apparently not seen very thorough tests, I am wondering if there are any additional “surprises”...

 

answered