vab_13
ServiceNow Employee
ServiceNow Employee

Hi,

For your SSO integrations: All of a sudden, if you start seeing "SAML Response Invalid" or redirects to the logout page, below will help with your investigation.

In most of the cases, it's caused either by a certificate update at your SSO IDP(SingleSignOn Identity Provider), or some config update at your IDP.

For the case of a certificate update at your IDP:

A quick fix is to read the new certificate from ServiceNow logs and configure it to fix the issue.

If you have got MultiSSO or SAML2Update1 plugin: you will need to enable debug to be able to read the certificate from logs.

Perform following:

1. Connect to your instance using an Admin local account (i.e OOB System Administrator account "admin"). You can user side_door.do OR login.do. You might need to contact ServiceNow Tech Support if you have disabled both for your instance.

2. Go to: "System Definition" => "Scripts - Background"

3. Execute below script:

====

                                                                                             

                                                                                   

                                                                                              var minAgo = 20;

                                                                                              gs.print("\n\nIs SAML2Update1 plugin enabled? => " +gs.getProperty("glide.authenticate.external") +

                                                                                                                              "\nIs SAML2Update1 debug enabled?   => " +gs.getProperty("glide.authenticate.sso.saml2.debug")+

                                                                                                                              "\n--------------------------- \nIs MultiSSO plugin enabled? =====> " +gs.getProperty("glide.authenticate.multisso.enabled")+

                                                                                                                              "\nIs MultiSSO debug enabled? ======> " +gs.getProperty("glide.authenticate.multisso.debug")+

                                                                                                                              "\n---------------------------\n");

                                                              if( gs.getProperty("glide.authenticate.multisso.debug") == "true" || gs.getProperty("glide.authenticate.sso.saml2.debug") == "true"){

                                                                                              var logCerti = new GlideRecord('syslog');

                                                                                              logCerti.addQuery('sys_created_on', '>=', gs.minutesAgo(minAgo));

                                                                                              logCerti.addQuery('message','CONTAINS','<ds:X509Certificate>');

                                                                                              logCerti.addQuery('message','CONTAINS','</ds:X509Certificate>');

                                                                                              logCerti.query();

                                                                                              var logCertiMessageArray = [];

                                                                                              var i = 0;

                                                                                              while(logCerti.next()){

                                                                                                                              logCertiMessageArray[i] = logCerti.getValue("message");

                                                                                                                              i++;

                                                                                              }

                                                                                              var noDuplicates = new ArrayUtil().unique(logCertiMessageArray);

                                                                                              gs.print("\n\n===============================================================================\n=======================CERTIFICATES FOUND IN LOGS==============================\n===============================================================================\n");

                                                                                              for(var i=0; i<noDuplicates.length; i++){

                                                                                                                              var certificate = noDuplicates[i].substring(noDuplicates[i].lastIndexOf("<ds:X509Certificate>") + 20, noDuplicates[i].lastIndexOf("<ds:X509Certificate>") + 992);

                                                                                                                              gs.print("\n\n\n-----BEGIN CERTIFICATE-----\n"+certificate+"\n-----END CERTIFICATE-----\n\n\n");

                                                                                              }

                                                              }

                                                              else{

                                                                                              gs.print("Multi SSO / SAML2Update1 Debug is not enabled : Please Enable Debug and try again.");

                                                                                              gs.setAbortAction(true);

                                                              }

                                                              if( gs.getProperty("glide.authenticate.multisso.enabled") == "true" && gs.getProperty("glide.authenticate.multisso.debug") == "true"){

                                                                                              //Code to Print Active IDP Recordsin the system, along with mapping Certificates

                                                                                              var activeIdpRecordsName = [];

                                                                                              var activeIdpRecordsURL = [];

                                                                                              var activeIdpRecordsSysID = [];

                                                                                              var idpRecords = new GlideRecord("sso_properties");

                                                                                              idpRecords.addQuery('active','true');

                                                                                              idpRecords.query();

                                                                                              i=0;

                                                                                              while(idpRecords.next()){

                                                                                                                              activeIdpRecordsName[i]=idpRecords.getValue("name");

                                                                                                                              activeIdpRecordsURL[i]=idpRecords.getValue("idp");

                                                                                                                              activeIdpRecordsSysID[i]=idpRecords.getValue("sys_id");

                                                                                                                              i++;

                                                                                              }

                                                                                              gs.print("\n\n=================================================================\n====================ACTIVE IDP DETAILS===========================\n=================================================================\n");

                                                                                              for(var j=0; j<activeIdpRecordsName.length; j++){

                                                                                                                              gs.print(

                                                                                                                              "\n\nIDP Name => "+activeIdpRecordsName[j]+

                                                                                                                              "\nIDP URL ==> "+activeIdpRecordsURL[j]+"\n");

                                                                                              }

                                                                                              var idpCertificateSysId = [];

                                                                                              var mappedCertificates = new GlideRecord('idp_certificate');

                                                                                              for(var j=0;j<=i;j++)

                                                                                                                              mappedCertificates.addOrCondition('idp',activeIdpRecordsSysID[j]);

                                                                                              mappedCertificates.query();

                                                                                              i=0;

                                                                                              while(mappedCertificates.next()){

                                                                                                                              idpCertificateSysId[i] = mappedCertificates.getValue("x509_certificate");

                                                                                                                              i++;

                                                                                              }

                                                                                              var idpCertificateText=[];

                                                                                              var idpCertificateDate=[];

                                                                                              var idpCertificateName=[];

                                                                                              var idpCertificateTextObject = new GlideRecord('sys_certificate');

                                                                                              var certi = idpCertificateTextObject.addQuery('sys_id', idpCertificateSysId[0]);

                                                                                              for(var j=1; j<i;j++){

                                                                                                                              certi.addOrCondition('sys_id', idpCertificateSysId[j]);

                                                                                              }

                                                                                              idpCertificateTextObject.query();

                                                                                              i=0;

                                                                                              while(idpCertificateTextObject.next()){

                                                                                                                              idpCertificateText[i] = idpCertificateTextObject.getValue('pem_certificate');

                                                                                                                              idpCertificateDate[i] = idpCertificateTextObject.getValue("expires");

                                                                                                                              idpCertificateName[i] = idpCertificateTextObject.getValue("short_description");

                                                                                                                              i++;

                                                                                              }

                                                                                              gs.print("\n\n================================================================================\n==================ACTIVE IDP's MAPPED CERTIFICATE DETAILS=======================\n================================================================================\n");

                                                                                              for(i=0; i<idpCertificateText.length; i++){

                                                                                                                              gs.print(

                                                                                                                              "\n\nCertificate Name ======> "+idpCertificateName[i]+

                                                                                                                              "\nCertificate Expiring on => "+idpCertificateDate[i]+

                                                                                                                              "\nCertificate Value =======> \n"+idpCertificateText[i]+"\n\n\n\n");

                                                                                              }

                              }

                              if( gs.getProperty("glide.authenticate.external") == "true" && gs.getProperty("glide.authenticate.sso.saml2.debug") == "true"){

                                                              gs.print("\n\n IDP URL ==> "+gs.getProperty("glide.authenticate.sso.saml2.idp") +"\n\n" );

                                                              //Code to Print existing Active Certificates in the system, along with expiring date =>

                                                              var sysCertificate = new GlideRecord('sys_certificate');

                                                              sysCertificate.addQuery('active','true');

                                                              sysCertificate.query();

                                                              var activeCertificateValue=[];

                                                              var activeCertificateDate=[];

                                                              var activeCertificateName=[];

                                                              i=0;

                                                              while(sysCertificate.next()){

                                                                                              activeCertificateValue[i]=sysCertificate.getValue("pem_certificate");

                                                                                              activeCertificateDate[i]=sysCertificate.getValue("expires");

                                                                                              activeCertificateName[i]=sysCertificate.getValue("short_description");

                                                                                              i++;

                                                              }

                                                              gs.print("\n\n===============================================================================\n=================There are "+ ++i +" Active Certificates in the system=================\n===============================================================================\n");

                                                              for(var i=0; i<activeCertificateName.length; i++)

                                                              gs.print(

                                                                                              "\n\nCertificate Name ======> "+activeCertificateName[i]+

                                                                                              "\nCertificate Expiring on => "+activeCertificateDate[i]+

                                                                                              "\nCertificate Value =======> \n"+activeCertificateValue[i]+"\n\n\n\n");

                              }

         

====

This scripts scans last 30 mins logs and prints certificate coming in SAMLResponse of your IDP.

This script also prints active certificates in your instance.

If the certificate found in the logs is not there in the system: please validate and configure the certificate in ServiceNow to fix this issue OR perform a metadata import from IDP config page.:

Note: The metadata import process automatically creates a certificate record for the identity provider. Navigate to the x509 Certificate module to see the certificate.

=>Please take appropriate backups and test on dev instances before making any change to your Production Instance.

4. Output of this script:

=====

*** Script:

Is SAML2Update1 plugin enabled? => false

Is SAML2Update1 debug enabled?   => false

---------------------------

Is MultiSSO plugin enabled? =====> true

Is MultiSSO debug enabled? ======> false

---------------------------

*** Script:

==============================================================================

=======================CERTIFICATES FOUND IN LOGS==============================

==============================================================================

*** Script:

-----BEGIN CERTIFICATE-----

MIIC3DCCAcSgAwIBAgIQFnoPNU/bM4BIvmx+fEhc2zANBgkqhkiG9w0BAQsFADAqMSgwJgYDVQQDEx9BREZTIFNpZ25pbmcgLSBzdHMuYW1lcmlnYXMuY29tMB4XDTE2MTEwODAxMjYyOFoXDTE5MTEwODAxMjYyOFowKjEoMCYGA1UEAxMfQURGUyBTaWduaW5nIC0gc3RzLmFtZXJpZ2FzLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIeJ29AQSP8X48KlbMc7l0o4rLKjbHqgqplomlPn1GmVKJT3cx72EpMKf/ccWA17uz8wx0yXSV9eMV42ytkRR7XwfWMoB779/TDrhwZWUrf0/GHEIcItZyiEOAFqRLIhGm/duxLKNNtp7sOThCO2RpZSVbdL6efevIOH+BXEMO/P6AFHsnNVAhS5q3U03BCA4goXIzkEDjK9N6dN7NpabW5nHlfjmEOItOXlsquQU2kUFz1Qu8ARlyehFeZbq9UFwSabIVOr0JfOZ1v29bLqteGHb0I+RHtk99JkuRnYeYfD5Jf5Eq5Ce5HM2CNpA2brUUOKBLtqelzFyiz7bqQCc1MCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAH0Cfh29y5tL8kebBjB3dhbWZ16W/nyee+avuugrvJuSh+/uVJ4WExWRnylXdVoergYe56JcHa5NJXS6qQtB8WermsXnt+kTycWW1yl80n9v5XTaKqIyvc4ag6j+JVZ2AwuwXwq9K9GG5caQgGG8jRFYfbOXNVtzLSdTA9GXtTJvyvsXkSZuq564+4kiukSaVRInEtKtyrW2zZr7h8zaBZvY7xa8ITyMAS2ivAO1m3m3v+r4ZYPUFzdEW8gZTuevGTlzCv7Ogkkl5G4Kjyscl+AGbIid8HP3ogYAfdXqATWqpZUPu3ZeJY7aU0JCJQGk9jHe0l9RjP9PwATvKGwxzgw==

-----END CERTIFICATE-----

*** Script:

=================================================================

====================ACTIVE IDP DETAILS===========================

=================================================================


*** Script:

IDP Name => Digested Token

IDP URL ==> URL.URL@URL.TEST

*** Script:

================================================================================

==================ACTIVE IDP's MAPPED CERTIFICATE DETAILS=======================

================================================================================

*** Script:

Certificate Name ======> idp.ssocircle.com

Certificate Expiring on => 2016-08-17 19:57:21

Certificate Value =======>

-----BEGIN CERTIFICATE-----

MIICjDCCAXSgAwIBAgIFAJRvxcMwDQYJKoZIhvcNAQEEBQAwLjELMAkGA1UEBhMCREUxEjAQBgNVBAoTCVNTT0NpcmNsZTELMAkGA1UEAxMCQ0EwHhcNMTEwNTE3MTk1NzIxWhcNMTYwODE3MTk1NzIxWjBLMQswCQYDVQQGEwJERTESMBAGA1UEChMJU1NPQ2lyY2xlMQwwCgYDVQQLEwNpZHAxGjAYBgNVBAMTEWlkcC5zc29jaXJjbGUuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbzDRkudC/aC2gMqRVVaLdPJJEwpFB4o71fR5bnNd2ocnnNzJ/W9CoCargzKx+EJ4Nm3vWmX/IZRCFvrvy9C78fP1cmt6Sa091K9luaMAyWn7oC8h/YBXH7rB42tdvWLY4Kl9VJy6UCclvasyrfKx+SR4KU6zCsM622Kvp5wW67QIDAQABoxgwFjAUBglghkgBhvhCAQEBAf8EBAMCBHAwDQYJKoZIhvcNAQEEBQADggEBAJ0heua7mFO3QszdGu1NblGaTDXtf6Txte0zpYIt+8YUcza2SaZXXvCLb9DvGxW1TJWaZpPGpHz5tLXJbdYQn7xTAnL4yQOKN6uNqUA/aTVgyyUJkWZt2giwEsWUvG0UBMSPS1tp2pV2c6/olIcbdYU6ZecUz6N24sSS7itEBC6nwCVBoHOL8u6MsfxMLDzJIPBI68UZjz3IMKTDUDv6U9DtYmXLc8iMVZBncYJn9NgNi3ghl9fYPpHcc6QbXeDUjhdzXXUqG+hB6FabGqdTdkIZwoi4gNpyr3kacKRVWJssDgakeL2MoDNqJyQ0fXC6Ze3f79CKy/WjeU5FLwDZR0Q=

-----END CERTIFICATE-----

=====

5. Compare the certificate found in the logs with the active one configured in the system

6. If the certificate is different, check the expiry date of the active certificates in the system. In most of the cases, IDP updates the certificate but skips to inform ServiceNow Admin about it.

7. If the expiry is in near future - that gives more surety about it being a certificate issue.

8. You can try configuring this new certificate found in the system and mapping it to your IDP record in ServiceNow to see if that fixes your issue OR contact your IDP with these details to get a confirmation before making a change: this is your call.

=> Please make sure you perform all needful investigation, take required backups and TEST before concluding on what need to be updated in your ServiceNow instance.

Regards,

Vab Singhal

Comments
aaronnow
Kilo Contributor

Thanks for the script Vab, we leveraged this script and fixed our Prod issue just now!!!


Version history
Last update:
‎12-28-2016 04:54 PM
Updated by: