Help setting up XDMoD 10.0 Dashboard integrated in OOD 2.0.28 and Keyclock(SAML) Single Sign On Authentication

A blank page makes me think something in the PHP stack is broken like syntax mistake in authsources.php or something. I’d check both Apache logs and XDMOD logs to see if maybe it’s printing any errors. The Apache logs on XDMOD side should be in /var/log/httpd and XDMOD is at /var/log/xdmod. If there are PHP errors I think those would make their way into the Apache logs.

OK, I added ‘directory’ => ‘/etc/xdmod/simplesamlphp/metadata/’ nano /etc/xdmod/simplesamlphp/config/config.php

...
'metadata.sources' => array(
     array('type' => 'flatfile', 'directory' => '/etc/xdmod/simplesamlphp/metadata/'),
   ),
...

It’s in the documentation: https://open.xdmod.org/10.0/simpleSAMLphp.html

Now I have the XDMoD page with login

You will have to check the Keycloak logs as to what the error is around the processing of the response. I can’t really advise where those logs would be since it’s really unique depending on how you installed Keycloak. I run Keycload under a systemd service with logging to stdout so the logs end up in journald and syslog.

I enabled Keycloak logs and caught the Java error when I logged into XDMoD:

2022-11-07 21:34:45,528 INFO  [org.keycloak.services] (executor-thread-5) KC-SERVICES0106: Created script engine 'Oracle Nashorn', version '11.0.16.1' for the mime type 'text/javascript'
2022-11-07 21:34:46,501 ERROR [org.keycloak.protocol.saml.SamlProtocol] (executor-thread-5) failed: org.keycloak.saml.common.exceptions.ProcessingException: failed to encrypt
        at org.keycloak.saml.BaseSAML2BindingBuilder.encryptDocument(BaseSAML2BindingBuilder.java:253)
        at org.keycloak.saml.BaseSAML2BindingBuilder$BasePostBindingBuilder.<init>(BaseSAML2BindingBuilder.java:154)
        at org.keycloak.protocol.saml.JaxrsSAML2BindingBuilder$PostBindingBuilder.<init>(JaxrsSAML2BindingBuilder.java:49)
        at org.keycloak.protocol.saml.JaxrsSAML2BindingBuilder.postBinding(JaxrsSAML2BindingBuilder.java:105)
        at org.keycloak.protocol.saml.SamlProtocol.buildAuthenticatedResponse(SamlProtocol.java:551)
        at org.keycloak.protocol.saml.SamlProtocol.authenticated(SamlProtocol.java:542)
        at org.keycloak.services.managers.AuthenticationManager.redirectAfterSuccessfulFlow(AuthenticationManager.java:968)
        at org.keycloak.services.managers.AuthenticationManager.redirectAfterSuccessfulFlow(AuthenticationManager.java:916)
        at org.keycloak.services.managers.AuthenticationManager.finishedRequiredActions(AuthenticationManager.java:1069)
        at org.keycloak.authentication.AuthenticationProcessor.authenticationComplete(AuthenticationProcessor.java:1131)
        at org.keycloak.authentication.AuthenticationProcessor.authenticationAction(AuthenticationProcessor.java:998)
        at org.keycloak.services.resources.LoginActionsService.processFlow(LoginActionsService.java:321)
        at org.keycloak.services.resources.LoginActionsService.processAuthentication(LoginActionsService.java:292)
        at org.keycloak.services.resources.LoginActionsService.authenticate(LoginActionsService.java:276)
        at org.keycloak.services.resources.LoginActionsService.authenticateForm(LoginActionsService.java:349)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:170)
        at org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
        at org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:660)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:524)
        at org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:474)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:476)
        at org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:434)
        at org.jboss.resteasy.core.ResourceLocatorInvoker.invokeOnTargetObject(ResourceLocatorInvoker.java:192)
        at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:141)
        at org.jboss.resteasy.core.ResourceLocatorInvoker.invoke(ResourceLocatorInvoker.java:32)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:492)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:261)
        at org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:161)
        at org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
        at org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:164)
        at org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:247)
        at io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:151)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:82)
        at io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.handle(VertxRequestHandler.java:42)
        at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212)
        at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163)
        at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
        at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:67)
        at io.quarkus.vertx.http.runtime.StaticResourcesRecorder$2.handle(StaticResourcesRecorder.java:55)
        at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212)
        at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163)
        at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
        at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:380)
        at io.quarkus.vertx.http.runtime.VertxHttpRecorder$5.handle(VertxHttpRecorder.java:358)
        at io.vertx.ext.web.impl.RouteState.handleContext(RouteState.java:1212)
        at io.vertx.ext.web.impl.RoutingContextImplBase.iterateNext(RoutingContextImplBase.java:163)
        at io.vertx.ext.web.impl.RoutingContextImpl.next(RoutingContextImpl.java:141)
        at org.keycloak.quarkus.runtime.integration.web.QuarkusRequestFilter.lambda$createBlockingHandler$1(QuarkusRequestFilter.java:71)
        at io.vertx.core.impl.ContextImpl.lambda$null$0(ContextImpl.java:159)
        at io.vertx.core.impl.AbstractContext.dispatch(AbstractContext.java:100)
        at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$1(ContextImpl.java:157)
        at io.quarkus.vertx.core.runtime.VertxCoreRecorder$13.runWith(VertxCoreRecorder.java:543)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: java.lang.RuntimeException: PL00069: Parser: Type not supported:unsupported publicKey Algo:EC
        at org.keycloak.saml.common.DefaultPicketLinkLogger.unsupportedType(DefaultPicketLinkLogger.java:174)
        at org.keycloak.saml.processing.core.util.XMLEncryptionUtil.getXMLEncryptionURLForKeyUnwrap(XMLEncryptionUtil.java:466)
        at org.keycloak.saml.processing.core.util.XMLEncryptionUtil.encryptKey(XMLEncryptionUtil.java:95)
        at org.keycloak.saml.processing.core.util.XMLEncryptionUtil.encryptElement(XMLEncryptionUtil.java:135)
        at org.keycloak.saml.BaseSAML2BindingBuilder.encryptDocument(BaseSAML2BindingBuilder.java:249)
        ... 63 more

There is something messed up with the encryption between simplesamlphp and Keycloak for SAML. I have never had that issue before with XDMOD but with other SAML services I don’t control I’ve seen that error. I’d recommend for the Keycloak client for XDMOD disable Encrypt Assertions. Not the most secure so might be worth making sure you have the certs correct in Keycloak and correctly setup on XDMOD in simplesamlphp.

Correct, in Keycloak we no longer have the error. Then I solve this problem of certificates to re-enable Encrypt Assertions.
Now changed to:

I’m not sure where that error would come from in XDMOD. Might have to send help request to XDMOD folks Open XDMoD - Support.

I installed all my power and configured everything again and now I have this:

When I log into XDMoD

I think you’ll have to open a support ticket with XDMOD developers as I’ve never seen that error before. The only thing I can think that might be the issue is your instance of XDMOD has no job data for your username so your username doesn’t exist in database but that shouldn’t cause an exception.

Hello Leonardo, could you explain mean by I installed all my power and configured everything again. I’m having the same issue as you, Using Simplesamlphp as my SP and testsaml.id as my idp. Seeing the Access forbidden error.

Greetings, Kris! I’ve been on a journey to implement XDMoD in OOD with Keycloak as you can see in this long topic which I’ve been getting help from Trey Dockendorf and Jeff Ohrstrom. Many of the issues have been fixed and there are some details that make a difference. If your case is the same, we can try to follow and solve it. If you need any details on what I’ve done so far, don’t hesitate to ask. I also opened a ticket at Support : Center for Computational Research and am awaiting a return.

I believe the Access forbidden error you saw (after configuring your SP -simplesamlphp, with your idp -keycloak) was resolved by disabling Encrypt Assertions in your SP. Could you post a code snippet of it, if that is the case.

The Encrypt Assertions can be disabled in Keycloak web UI on the Client page for XDMOD’s SAML client. Should be unnecessary if encryption is setup correctly between simplsamlphp and Keycloak.

As for disabling encryptions, I’m doing it temporarily. The goal is to make the thing work and then I’ll work on security and rehabilitate whatever is necessary.

I dont see an attribute Encrypt Assertions in my SP or IDP
Here’s the error I’m seeing. I believe its similar (if not same) as the one described by Leonardo Loures

The difference is I’m using samltest as idp vs keycloak as described in this ticket.



The setting “Encrypt Assertions” is specific to Keycloak. I am not familiar with any other IDP besides Keycloak. The error you are facing is specific to XDMOD so likely need to open a case with that product’s support.

I had to do some settings in the authsources.php and config.php files that made a difference. I don’t know how yours are.
For example in config.php

...
'enable.saml20-idp' => true,
...
'metadata.sources' => array(
     array('type' => 'flatfile', 'directory' => '/etc/xdmod/simplesamlphp/metadata/'),

I believe you also configured the files:

/etc/ood/config/ondemand.d/ondemand.yml
/etc/ood/config/nginx_stage.yml
/etc/ood/config/clusters.d/cluster.yml
/etc/xdmod/portal_settings.ini

I have both those changes in authsources.php and config.php.
And regarding the “Encrypt Assertions” change suggested by @tdockendorf , seems like samltest defaults to false for Encrypt Assertions. Ref. SimpleSAMLphp Documentation.

I believe it was something on your SP end that got you past the Access forbidden error.

and the only Assertions attributes I see in my SP’s metadata is

<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://xdmod.rc.uab.edu/simplesaml/module.php/saml/sp/saml2-logout.php/default-sp"/> <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" Location="https://xdmod.rc.uab.edu/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp" index="0"/> <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:browser-post" Location="https://xdmod.rc.uab.edu/simplesaml/module.php/saml/sp/saml1-acs.php/default-sp" index="1"/> <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" Location="https://xdmod.rc.uab.edu/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp" index="2"/> <md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:1.0:profiles:artifact-01" Location="https://xdmod.rc.uab.edu/simplesaml/module.php/saml/sp/saml1-acs.php/default-sp/artifact" index="3"/> </md:SPSSODescriptor>

and none in my idp’s metadata that I downloaded.

How is your XDMoD panel in OOD? Mine is like this: