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

I believe both XDMOD and OOD clients in Keycloak must be in same Realm in order for SSO to work. I’ve never tried doing it any other way so I can’t speak from experience.

In:
/etc/xdmod/portal_settings.ini

[cors]
domains = "https://ondemand.domain, https://keycloak.domain/"

In:
/etc/xdmod/simplesamlphp/config/authsources.php

<?php

$config = array(

    'default-sp' => array(
        'saml:SP',

        'entityID' => 'https://keycloak.domain/realms/oondemand',

        'idp' => 'https://keycloak.domain/realms/oondemand/protocol/saml/descriptor',

        'privatekey' => '/etc/xdmod/simplesamlphp/cert/xdmod.key',
        'certificate' => '/etc/xdmod/simplesamlphp/cert/xdmod.crt',

        'discoURL' => null,

        'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',

        'authproc' => array(
            40 => array(
              'class' => 'core:AttributeMap',
              'urn:oid:0.9.2342.19200300.100.1.1' => 'username',
              'urn:oid:1.2.840.113549.1.9.1' => 'email_address',
              'urn:oid:2.5.4.42' => 'first_name',
              'urn:oid:2.5.4.4' => 'last_name'
            )
        )
    ),

    'admin' => array(
        'core:AdminPassword',
    ),

);

In:
/etc/xdmod/simplesamlphp/config/config.php

*'secretsalt' => 'mumm000u0u2muamu200u22uauu20mu2a' # LC_CTYPE=C tr -c -d 'aamu02' </dev/urandom | dd bs=32 count=1 2>/dev/null;echo
...
'auth.adminpassword' => 'cGeQbpkyVSJoqisVCVvep4WpCztZYxZmkwUR8MTnRUqrgqRPch92Sw==' # /usr/share/xdmod/vendor/simplesamlphp/simplesamlphp/bin/pwgen.php 
...
'technicalcontact_email' => 'luvres@hotmail.com',
...
  'metadata.sources' => array(
    array('type' => 'flatfile', 'directory' => '/etc/xdmod/simplesamlphp/metadata/'),
  ),

If I’m on the right path, this part of the /etc/xdmod/simplesamlphp/metadata/saml20-idp-remote.php file generation is missing

Looks like you have to os here. o-o-n-demand. @jpwhite4 may know more.

At https://xdmod.domain/simplesaml/module.php/core/frontpage_federation.php you have the options:

XML to SimpleSAMLphp metadata converter
thought about converting the XML from https://keycloak.domain/realms/oondemand/protocol/saml/descriptor
in
Show metadata is generated an In SAML 2.0 Metadata XML format and a converted text that says:
In SimpleSAMLphp flat file format - use this if you are using a SimpleSAMLphp entity on the other side

I’ve been going through the settings quickly and many attempts…I still don’t understand what’s missing.

Yes, they are in the same realm called oondemand
The OOD client is called oondemand (same name as the realm) and the XDMoD client is called xdmod.domain

You get saml20-idp-remote.php from Keycloak. That is the curl commands in the post you saw here: Help setting up XDMoD and Keyclock(SAML) - #3 by tdockendorf. The URL might be slightly different on newer versions of Keycloak. For Keycloak 17+ it will be https://<keycloak server>/realms/<realm>/protocol/saml/descriptor. You can also get it by viewing the available protocols on Realm page inside Keycloak web UI. I believe you pass that descriptor information into simplsamlphp to generate the PHP file you need. I think it’s the metadata converter link.

When I generate the saml20-idp-remote.php file with XML to SimpleSAMLphp metadata convert getting the XML content at https://oidc.puc-rio.eu.org/realms/oondemand/protocol/saml/descriptor I have two conditions:

In authsources.php

  1. When 'idp' => 'https://keycloak.domain/realms/oondemand',

  2. When 'idp' => 'https://keycloak.domain/realms/oondemand/protocol/saml/descriptor',

It’s quite complicated to implement this solution. I find it strange and I’m wondering if the settings have changed for the new versions of the tools. I use Keycloak 18.0.2, Open XDMoD 10.0 and Open OnDemand 2.0.28

The idp value is not the descriptor path, it’s the SAML EntityID so it’s https://<keycloak server>/realms/<realm>. The entityID is autogenerated by Keycloak so you can’t change it which is why the format is always the same. Before Keycloak 17 it was a little different but still same idea. The descriptor URL is how you generate the SAML metadata but that’s just for populating the saml20-idp-remote.php.

The Client you create in Keycloak for XDMOD must have the name that matches the entityID in authsources.php. So if the entityID is xdmod.domain then that must be the name of the Client in Keycloak otherwise the SAML assertions won’t match anything in Keycloak.

My client on keycloak

My file authsources.php

<?php

$config = array(

    'default-sp' => array(
        'saml:SP',

        'entityID' => 'xdmod.exacta.eu.org',
        'idp' => 'https://oidc.puc-rio.eu.org/realms/oondemand',

        'privatekey' => '/etc/xdmod/simplesamlphp/cert/xdmod.key',
        'certificate' => '/etc/xdmod/simplesamlphp/cert/xdmod.crt',

        'discoURL' => null,

        'signature.algorithm' => 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',

        'authproc' => array(
            40 => array(
              'class' => 'core:AttributeMap',
              'urn:oid:0.9.2342.19200300.100.1.1' => 'username',
              'urn:oid:1.2.840.113549.1.9.1' => 'email_address',
              'urn:oid:2.5.4.42' => 'first_name',
              'urn:oid:2.5.4.4' => 'last_name'
            )
        )
    ),

    'admin' => array(
        'core:AdminPassword',
    ),

);

Page to generate saml20-idp-remote.php

Sorry for all this work, but I’m really freaking out about this!

This is when I generate the XML contained in
https://oidc.puc-rio.eu.org/realms/oondemand/protocol/saml/descriptor

And my saml20-idp-remote.php

So I disabled Client Signature Required and now I am redirected to the login screen as expected.

image

But now I get Failed to process response after login

Have you verified that XDMOD logins with Keycloak are working outside OnDemand? Just going into XDMOD and trying to login. It’s not clear from screenshots what you’re attempting to log into. Also the screenshots don’t show all the configurations for Keycloak for the XDMOD client. It’s a lot easier to see API dumps.

Example:

# /opt/keycloak/bin/kcadm.sh get clients -r <REALM> -q clientId=<XDMOD CLIENTID> --no-config --server http://localhost:8080/ --realm master --user admin --password <OMIT>  

Some important things I see in our config:

"clientId" : "<MUST MATCH entityID on XDMOD side>",
"webOrigins" : [ "https://<XDMOD HOST>" ],
"redirectUris" : [ "https://<XDMOD HOST>/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp" ],
  "attributes" : {
    "saml_assertion_consumer_url_post" : "https://<XDMOD HOST>/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp",
    "saml_single_logout_service_url_redirect" : "https://<XDMOD HOST>/simplesaml/module.php/saml/sp/saml2-logout.php/default-sp",
  },
  "defaultClientScopes" : [ "osc-saml-clients" ],

Also need to ensure you have the proper scopes otherwise XDMOD’s SAML can’t get things like username and email.

This is assined to osc-saml-clients from above.

{
  "id" : "osc-saml-clients",
  "name" : "osc-saml-clients",
  "protocol" : "saml",
  "attributes" : {
    "display.on.consent.screen" : "true"
  },
  "protocolMappers" : [ {
    "id" : "fe623cbe-1519-5fce-b043-a23f8ee50fe2",
    "name" : "X500 surname",
    "protocol" : "saml",
    "protocolMapper" : "saml-user-property-mapper",
    "consentRequired" : false,
    "config" : {
      "attribute.nameformat" : "URI Reference",
      "user.attribute" : "lastName",
      "friendly.name" : "surname",
      "attribute.name" : "urn:oid:2.5.4.4"
    }
  }, {
    "id" : "ef9766fd-9b1a-5ef5-b73f-9f88bf472e22",
    "name" : "X500 email",
    "protocol" : "saml",
    "protocolMapper" : "saml-user-property-mapper",
    "consentRequired" : false,
    "config" : {
      "attribute.nameformat" : "URI Reference",
      "user.attribute" : "email",
      "friendly.name" : "email",
      "attribute.name" : "urn:oid:1.2.840.113549.1.9.1"
    }
  }, {
    "id" : "197e693a-927d-5e66-8d90-f4ae7864c69e",
    "name" : "X500 givenName",
    "protocol" : "saml",
    "protocolMapper" : "saml-user-property-mapper",
    "consentRequired" : false,
    "config" : {
      "attribute.nameformat" : "URI Reference",
      "user.attribute" : "firstName",
      "friendly.name" : "givenName",
      "attribute.name" : "urn:oid:2.5.4.42"
    }
  }, {
    "id" : "a1c39d71-82d8-5a7a-a002-f1726a33f4dd",
    "name" : "username",
    "protocol" : "saml",
    "protocolMapper" : "saml-user-property-mapper",
    "consentRequired" : false,
    "config" : {
      "attribute.nameformat" : "URI Reference",
      "user.attribute" : "username",
      "friendly.name" : "userid",
      "attribute.name" : "urn:oid:0.9.2342.19200300.100.1.1"
    }
  }, {
    "id" : "b3ca3cd4-20a3-42af-a056-0002543c1004",
    "name" : "role list",
    "protocol" : "saml",
    "protocolMapper" : "saml-role-list-mapper",
    "consentRequired" : false,
    "config" : {
      "single" : "false",
      "attribute.nameformat" : "Basic",
      "attribute.name" : "Role"
    }
  } ]
}

/opt/keycloak/bin/kcadm.sh get clients -r oondemand -q clientId=xdmod.exacta.eu.org --no-config --server http://localhost:8080/ --realm master --user admin --password OMIT

[ {
  "id" : "08d22822-b1c7-4005-b23c-6748e17c263a",
  "clientId" : "xdmod.exacta.eu.org",
  "name" : "Open XDMoD",
  "rootUrl" : "",
  "adminUrl" : "",
  "surrogateAuthRequired" : false,
  "enabled" : true,
  "alwaysDisplayInConsole" : false,
  "clientAuthenticatorType" : "client-secret",
  "redirectUris" : [ "https://xdmod.exacta.eu.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp" ],
  "webOrigins" : [ "https://xdmod.exacta.eu.org" ],
  "notBefore" : 0,
  "bearerOnly" : false,
  "consentRequired" : false,
  "standardFlowEnabled" : true,
  "implicitFlowEnabled" : false,
  "directAccessGrantsEnabled" : false,
  "serviceAccountsEnabled" : false,
  "publicClient" : false,
  "frontchannelLogout" : true,
  "protocol" : "saml",
  "attributes" : {
    "saml.multivalued.roles" : "false",
    "saml.force.post.binding" : "true",
    "frontchannel.logout.session.required" : "false",
    "oauth2.device.authorization.grant.enabled" : "false",
    "backchannel.logout.revoke.offline.tokens" : "false",
    "saml.server.signature.keyinfo.ext" : "false",
    "use.refresh.tokens" : "true",
    "saml.signing.certificate" : "MIICpTCCAkugAwIBAgIUE8EgGPP5OJoBKk14BSpUx5AnW/0wCgYIKoZIzj0EAwIwgZIxCzAJBgNVBAYTAkJSMRcwFQYDVQQIEw5SaW8gZGUgSmFuZWlybzEXMBUGA1UEBxMOUmlvIGRlIEphbmVpcm8xFDASBgNVBAoTC0NsdXN0ZXIgSFBDMQswCQYDVQQLEwJDQTEuMCwGA1UEAxMlQ2xvdWRmbGFyZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0yMjA4MDgwNDA3MDBaFw0zMjA4MDUwNDA3MDBaMH4xCzAJBgNVBAYTAkJSMRcwFQYDVQQIEw5SaW8gZGUgSmFuZWlybzEXMBUGA1UEBxMOUmlvIGRlIEphbmVpcm8xFDASBgNVBAoTC0NsdXN0ZXIgSFBDMRcwFQYDVQQLEw5DbG91ZGZsYXJlIFNTTDEOMAwGA1UEAxMFY2Zzc2wwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQU/GNl15NedHjk6e3T+ExnVVPo9bRBq05q7FQKxNPSVbiwC6PZijc0zI0tvovGYfFE0w3v1J8fgpmMsijzSTmmo4GRMIGOMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUjQtfxjAWtz0ngXV4sIYJtQuVebEwHwYDVR0jBBgwFoAUEmgNfBT64HbI20iDALzZsXyTAqcwDwYDVR0RBAgwBocEfwAAATAKBggqhkjOPQQDAgNIADBFAiAK4akkV78dUN+2a+Zp+yBivumA/NxPULJ50f1kF5J6sQIhAJUvlx0IO6Tq+D4iSI+/uYy29CgQsg+yXwDEPcLJqtoC",
    "oidc.ciba.grant.enabled" : "false",
    "backchannel.logout.session.required" : "false",
    "saml.signature.algorithm" : "RSA_SHA256",
    "client_credentials.use_refresh_token" : "false",
    "require.pushed.authorization.requests" : "false",
    "saml.client.signature" : "false",
    "saml.allow.ecp.flow" : "false",
    "saml.assertion.signature" : "false",
    "id.token.as.detached.signature" : "false",
    "client.secret.creation.time" : "1667705384",
    "saml.encrypt" : "true",
    "saml_assertion_consumer_url_post" : "https://xdmod.exacta.eu.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp",
    "saml.server.signature" : "true",
    "exclude.session.state.from.auth.response" : "false",
    "saml.artifact.binding.identifier" : "ZBVKrNNNSqJHVJm80zuYAOaKzJE=",
    "saml_single_logout_service_url_redirect" : "https://xdmod.exacta.eu.org/simplesaml/module.php/saml/sp/saml2-logout.php/default-sp",
    "saml.artifact.binding" : "false",
    "saml_force_name_id_format" : "true",
    "saml.encryption.certificate" : "MIICpTCCAkugAwIBAgIUE8EgGPP5OJoBKk14BSpUx5AnW/0wCgYIKoZIzj0EAwIwgZIxCzAJBgNVBAYTAkJSMRcwFQYDVQQIEw5SaW8gZGUgSmFuZWlybzEXMBUGA1UEBxMOUmlvIGRlIEphbmVpcm8xFDASBgNVBAoTC0NsdXN0ZXIgSFBDMQswCQYDVQQLEwJDQTEuMCwGA1UEAxMlQ2xvdWRmbGFyZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0yMjA4MDgwNDA3MDBaFw0zMjA4MDUwNDA3MDBaMH4xCzAJBgNVBAYTAkJSMRcwFQYDVQQIEw5SaW8gZGUgSmFuZWlybzEXMBUGA1UEBxMOUmlvIGRlIEphbmVpcm8xFDASBgNVBAoTC0NsdXN0ZXIgSFBDMRcwFQYDVQQLEw5DbG91ZGZsYXJlIFNTTDEOMAwGA1UEAxMFY2Zzc2wwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQU/GNl15NedHjk6e3T+ExnVVPo9bRBq05q7FQKxNPSVbiwC6PZijc0zI0tvovGYfFE0w3v1J8fgpmMsijzSTmmo4GRMIGOMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUjQtfxjAWtz0ngXV4sIYJtQuVebEwHwYDVR0jBBgwFoAUEmgNfBT64HbI20iDALzZsXyTAqcwDwYDVR0RBAgwBocEfwAAATAKBggqhkjOPQQDAgNIADBFAiAK4akkV78dUN+2a+Zp+yBivumA/NxPULJ50f1kF5J6sQIhAJUvlx0IO6Tq+D4iSI+/uYy29CgQsg+yXwDEPcLJqtoC",
    "tls.client.certificate.bound.access.tokens" : "false",
    "acr.loa.map" : "{}",
    "saml.authnstatement" : "true",
    "display.on.consent.screen" : "false",
    "saml_name_id_format" : "username",
    "token.response.type.bearer.lower-case" : "false",
    "saml_artifact_binding_url" : "https://xdmod.exacta.eu.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp",
    "saml_signature_canonicalization_method" : "http://www.w3.org/2001/10/xml-exc-c14n#",
    "saml.onetimeuse.condition" : "false"
  },
  "authenticationFlowBindingOverrides" : { },
  "fullScopeAllowed" : true,
  "nodeReRegistrationTimeout" : -1,
  "protocolMappers" : [ {
    "id" : "b399bbf5-23f4-45e3-a736-b42a9f5f6222",
    "name" : "username",
    "protocol" : "saml",
    "protocolMapper" : "saml-user-property-mapper",
    "consentRequired" : false,
    "config" : {
      "attribute.nameformat" : "Unspecified",
      "user.attribute" : "username",
      "friendly.name" : "username",
      "attribute.name" : "username"
    }
  } ],
  "defaultClientScopes" : [ "osc-saml-clients", "role_list" ],
  "optionalClientScopes" : [ ],
  "access" : {
    "view" : true,
    "configure" : true,
    "manage" : true
  }
} ]

Some web interface images for clients and client scope:

Can you log into XDMOD directly using Keycloak? The Client looks correct in Keycloak. The only thing odd I notice is you have a client scope for username assigned directly to the XDMOD Client in Keycloak but also seem to have that same scope defined in osc-saml-clients . I think you’d want to remove the one from XDMOD client since it doesn’t use the urn attribute name which I think makes a difference.

You’re right, I configured the username scoped directly in the XDMoD client in some configuration attempts. I just removed this.

[ {
  "id" : "08d22822-b1c7-4005-b23c-6748e17c263a",
  "clientId" : "xdmod.exacta.eu.org",
  "name" : "Open XDMoD",
  "rootUrl" : "",
  "adminUrl" : "",
  "surrogateAuthRequired" : false,
  "enabled" : true,
  "alwaysDisplayInConsole" : false,
  "clientAuthenticatorType" : "client-secret",
  "redirectUris" : [ "https://xdmod.exacta.eu.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp" ],
  "webOrigins" : [ "https://xdmod.exacta.eu.org" ],
  "notBefore" : 0,
  "bearerOnly" : false,
  "consentRequired" : false,
  "standardFlowEnabled" : true,
  "implicitFlowEnabled" : false,
  "directAccessGrantsEnabled" : false,
  "serviceAccountsEnabled" : false,
  "publicClient" : false,
  "frontchannelLogout" : true,
  "protocol" : "saml",
  "attributes" : {
    "saml.multivalued.roles" : "false",
    "saml.force.post.binding" : "true",
    "frontchannel.logout.session.required" : "false",
    "oauth2.device.authorization.grant.enabled" : "false",
    "backchannel.logout.revoke.offline.tokens" : "false",
    "saml.server.signature.keyinfo.ext" : "false",
    "use.refresh.tokens" : "true",
    "saml.signing.certificate" : "MIICpTCCAkugAwIBAgIUE8EgGPP5OJoBKk14BSpUx5AnW/0wCgYIKoZIzj0EAwIwgZIxCzAJBgNVBAYTAkJSMRcwFQYDVQQIEw5SaW8gZGUgSmFuZWlybzEXMBUGA1UEBxMOUmlvIGRlIEphbmVpcm8xFDASBgNVBAoTC0NsdXN0ZXIgSFBDMQswCQYDVQQLEwJDQTEuMCwGA1UEAxMlQ2xvdWRmbGFyZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0yMjA4MDgwNDA3MDBaFw0zMjA4MDUwNDA3MDBaMH4xCzAJBgNVBAYTAkJSMRcwFQYDVQQIEw5SaW8gZGUgSmFuZWlybzEXMBUGA1UEBxMOUmlvIGRlIEphbmVpcm8xFDASBgNVBAoTC0NsdXN0ZXIgSFBDMRcwFQYDVQQLEw5DbG91ZGZsYXJlIFNTTDEOMAwGA1UEAxMFY2Zzc2wwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQU/GNl15NedHjk6e3T+ExnVVPo9bRBq05q7FQKxNPSVbiwC6PZijc0zI0tvovGYfFE0w3v1J8fgpmMsijzSTmmo4GRMIGOMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUjQtfxjAWtz0ngXV4sIYJtQuVebEwHwYDVR0jBBgwFoAUEmgNfBT64HbI20iDALzZsXyTAqcwDwYDVR0RBAgwBocEfwAAATAKBggqhkjOPQQDAgNIADBFAiAK4akkV78dUN+2a+Zp+yBivumA/NxPULJ50f1kF5J6sQIhAJUvlx0IO6Tq+D4iSI+/uYy29CgQsg+yXwDEPcLJqtoC",
    "oidc.ciba.grant.enabled" : "false",
    "backchannel.logout.session.required" : "false",
    "saml.signature.algorithm" : "RSA_SHA256",
    "client_credentials.use_refresh_token" : "false",
    "require.pushed.authorization.requests" : "false",
    "saml.client.signature" : "false",
    "saml.allow.ecp.flow" : "false",
    "saml.assertion.signature" : "false",
    "id.token.as.detached.signature" : "false",
    "client.secret.creation.time" : "1667705384",
    "saml.encrypt" : "true",
    "saml_assertion_consumer_url_post" : "https://xdmod.exacta.eu.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp",
    "saml.server.signature" : "true",
    "exclude.session.state.from.auth.response" : "false",
    "saml.artifact.binding.identifier" : "ZBVKrNNNSqJHVJm80zuYAOaKzJE=",
    "saml_single_logout_service_url_redirect" : "https://xdmod.exacta.eu.org/simplesaml/module.php/saml/sp/saml2-logout.php/default-sp",
    "saml.artifact.binding" : "false",
    "saml_force_name_id_format" : "true",
    "saml.encryption.certificate" : "MIICpTCCAkugAwIBAgIUE8EgGPP5OJoBKk14BSpUx5AnW/0wCgYIKoZIzj0EAwIwgZIxCzAJBgNVBAYTAkJSMRcwFQYDVQQIEw5SaW8gZGUgSmFuZWlybzEXMBUGA1UEBxMOUmlvIGRlIEphbmVpcm8xFDASBgNVBAoTC0NsdXN0ZXIgSFBDMQswCQYDVQQLEwJDQTEuMCwGA1UEAxMlQ2xvdWRmbGFyZSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0yMjA4MDgwNDA3MDBaFw0zMjA4MDUwNDA3MDBaMH4xCzAJBgNVBAYTAkJSMRcwFQYDVQQIEw5SaW8gZGUgSmFuZWlybzEXMBUGA1UEBxMOUmlvIGRlIEphbmVpcm8xFDASBgNVBAoTC0NsdXN0ZXIgSFBDMRcwFQYDVQQLEw5DbG91ZGZsYXJlIFNTTDEOMAwGA1UEAxMFY2Zzc2wwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAQU/GNl15NedHjk6e3T+ExnVVPo9bRBq05q7FQKxNPSVbiwC6PZijc0zI0tvovGYfFE0w3v1J8fgpmMsijzSTmmo4GRMIGOMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUjQtfxjAWtz0ngXV4sIYJtQuVebEwHwYDVR0jBBgwFoAUEmgNfBT64HbI20iDALzZsXyTAqcwDwYDVR0RBAgwBocEfwAAATAKBggqhkjOPQQDAgNIADBFAiAK4akkV78dUN+2a+Zp+yBivumA/NxPULJ50f1kF5J6sQIhAJUvlx0IO6Tq+D4iSI+/uYy29CgQsg+yXwDEPcLJqtoC",
    "tls.client.certificate.bound.access.tokens" : "false",
    "acr.loa.map" : "{}",
    "saml.authnstatement" : "true",
    "display.on.consent.screen" : "false",
    "saml_name_id_format" : "username",
    "token.response.type.bearer.lower-case" : "false",
    "saml_artifact_binding_url" : "https://xdmod.exacta.eu.org/simplesaml/module.php/saml/sp/saml2-acs.php/default-sp",
    "saml_signature_canonicalization_method" : "http://www.w3.org/2001/10/xml-exc-c14n#",
    "saml.onetimeuse.condition" : "false"
  },
  "authenticationFlowBindingOverrides" : { },
  "fullScopeAllowed" : true,
  "nodeReRegistrationTimeout" : -1,
  "defaultClientScopes" : [ "osc-saml-clients", "role_list" ],
  "optionalClientScopes" : [ ],
  "access" : {
    "view" : true,
    "configure" : true,
    "manage" : true
  }
} ]

When I access xdmod url, after I create the /etc/xdmod/simplesamlphp/config/authsources.php file page returns blank

Without the authsources.php file the page works, but not the login.

I’m reviewing the settings.
in /etc/xdmod/simplesamlphp/config/config.php I enable 'enable.saml20-idp' => true

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.