Customization support in MultiSSOv2SummaryExcess customization can build up technical debt and lengthen your upgrade cycle, inhibiting your ability to take advantage of new features. Evaluate demands for customization very carefully and only resort to customization where there is clear business value and no alternative to satisfying demand. Before you plan to go for customizations, please review customization best practices for ServiceNow. Coming to MultiSSO, before you plan to modify the scripts please check if the same functionality can be achieved by configurations in the identity provider record. Some of the features which were not supported in previous releases or used to require customizations are now supported out-of-the-box (OOTB). Some examples are: HTTP-POST redirect bindingIDP initiated single logout (SLO) (Rome release onwards) In the MultiSSOv1 version, modifications used to be made in the SAML2_update1 and MultiSSO_SAML2_update1 script includes for customizations. Making changes to these OOTB scripts, used to create upgrade challenges. As ServiceNow upgrades will not overwrite customizations you have made but will mark them as skipped records in the ServiceNow Upgrade Monitor. To make sure they’re successfully ported to the upgraded instance, manual intervention was required for handling the skipped changes.To avoid these upgrade challenges, In the MultiSSOv2 version, we are changing the way customizations in OOTB implementation are supported.This KB provides a basic idea, how existing or new customizations can be incorporated in the MultiSSOv2 version.ReleaseThese instructions are valid for the MultiSSOv2 version, which is available in the New York release onwards. InstructionsIn order to reduce some of the upgrade challenges, core single sign-on script includes are made read-only for customers in MultiSSOv2. Additional script includes are provided specifically for applying customizations. These custom scripts extend the core scripts. Methods available in these read-only core script-includes can be overridden in the corresponding custom scripts. Extension points and supporting methods are also provided in the OOTB scripts to support various customization use cases.Note: ServiceNow will not make modifications to these custom scripts provided for customization purposes.Mapping of the script includes and Installation exits in MultiSSOv2 and MultiSSOv2 Feature Type Script to modify for Customization in v1 Read-only scripts with OOTB Implementation in MultiSSOv2 version Script to override the OOTB implementation forCustomization in MultiSSOv2 MultiSSO Script Include SAML2_update1 SAML2_internal SAML2_custom MultiSSO_SAML2_Update1 MultiSSOv2_SAML2_internal MultiSSOv2_SAML2_custom Installation Exit MultiSSO MultiSSOv2 MultiSSOLogout MultiSSOLogoutv2 E-signature Script Include ESignatureUtils ESignatureUtils SAML2_update1_esig SAML2_custom_esig While migrating existing customizations from the MultiSSOv1 version to MultiSSOv2, customers can override the OOTB behavior in custom scripts. For example: in MultiSSOv1, if the customizations were done in a particular method in the SAML2_update1 script include, the corresponding method will be available in SAML2_internal script include in the MultiSSOv2. The same method can be overridden in the SAML2_custom script include for customization. Similarly, if the customizations in MultiSSOv1 were in the MultiSSO_SAML2_Update1 script include, In MultiSSOv2 corresponding OOTB implementation is available in the MultiSSOv2_SAML2_internal script includes. The same method can be overridden in the MultiSSOv2_SAML2_custom script include for customizations. The same is applicable for SAML2_update1_esig to SAML2_custom_esig script includes. Overview of methods available in SMAL2_internal OOTB Authentication options for override Authn request options. forceAuthn to set the forceAuthn in AuthnRequest isPassive to set the AuthnRequest as passive in the script assertionConsumerServiceURL to set the assertion consumer service URL in the script while building custom Authn Request assertionConsumerServiceIndex to set the assertion consumer service index in the script while building custom Authn Request providerName to set the provider name in the script while building custom Authn Request skipNavFrame if the customer wants to render specific URLs or patterns without the navigation frame(for Portals etc), they can set skip a frame option. While generating relay state, nav_to will not be added to the URL and the page will be rendered without the navigation frame. deepLink if the customer wants to set a custom deep link or starting page for specific URLs or patterns, they can set this parameter. End-user will always be redirected to that deep-link post successful login. Example script for overriding getAuthnOptions method available in SAML2_internal script include in SAML2_custom script include. These examples are only for demonstration purposes. Please test your customizations thoroughly before applying those in the production instances. getAuthnOptions : function() { var authGenerationOptions = {}; if(this.isTestSAMLConnection()){ authGenerationOptions.forceAuthn = true; } return authGenerationOptions; }, Override in SAML2_custom like the example below gs.include("PrototypeServer"); var SAML2_custom = Class.create(); SAML2_custom.prototype = Object.extend(new SAML2_internal(), { initialize:function() { SAML2_internal.prototype.initialize.call(this); }, getAuthnOptions : function() { var authGenerationOptions = {}; if(this.isTestSAMLConnection()) { authGenerationOptions.forceAuthn = true; } //Customization for forceAuthn authGenerationOptions.forceAuthn = true; return authGenerationOptions; }, type: 'SAML2_custom' }); OOB Method available for customising SAML response validation Response validation options (true/false) available to support customizations. skip_responseissuer_checkskip_assertionissuer_checkskip_audiencerestriction_checkskip_onetimeuse_checkskip_proxyrestriction_checkskip_inresponseto_checkskip_sessionindex_checkskip_unknown_attribute_checksupport_httppost_login_only getValidationOptions: This method is to support customizations in SAML response validation. Method available in SAML2_internal getValidationOptions : function() { var responseValidationOptions = {}; return responseValidationOptions; }, Override in SAML2_custom like the example below. gs.include("PrototypeServer"); var SAML2_custom = Class.create(); SAML2_custom.prototype = Object.extend(new SAML2_internal(), { initialize:function() { SAML2_internal.prototype.initialize.call(this); }, getValidationOptions : function() { var responseValidationOptions = {}; responseValidationOptions. skip_sessionindex_check=true; return responseValidationOptions; }, type: 'SAML2_custom' }); Customizing AuthN request customizeAuthnRequest: if the Authn request customization cannot be achieved through the options available in getAuthnOptions method, customized Authn request can be build using GlideXML API and set the modified request using this method. Method available in SAML2_internal customizeAuthnRequest: function (xmlAuthnRequestElement) { return; }, Override in SAML2_custom like the example below. example script: create a scope using request DOM customizeAuthnRequest: function () { //Customization through Request DOM Element var xmlAuthnRequestElement = this.glidesaml2api.getGeneratedReqElemDOM(); var parentNameSpace = xmlAuthnRequestElement.getPrefix(); var scopingElement = GlideXMLUtil.newElement(xmlAuthnRequestElement, parentNameSpace + ":Scoping"); var idpListElement = GlideXMLUtil.newElement(scopingElement, parentNameSpace + ":IDPList"); var idpEntryElement = GlideXMLUtil.newElement(idpListElement, parentNameSpace + ":IDPEntry"); idpEntryElement.setAttribute('Name', 'uia.no'); idpEntryElement.setAttribute('ProviderID', this.getSSORecord().getValue('idp')); this.glidesaml2api.setCustomizedReqElemDOM(xmlAuthnRequestElement); //this is mandatory if the DOM is customized } Customizing Logout request customizeLogoutRequest: customize the logout request similar to the above example using GlideXML API and set the modified request using this method. The below example adds two extra attributes (NameQualifier and SPNameQualifier) to the NameID node which is obtained from an already built logout request element. customizeLogoutRequest: function() { var xmlRequestElement = this.glidesaml2api.getGeneratedReqElemDOM(); var nodeList = xmlRequestElement.getChildNodes(); var nameidElement = null; for (var i = 0; i < nodeList.getLength(); i++) { if ("saml2:NameID".equalsIgnoreCase(nodeList.item(i).getNodeName())) { nameidElement = nodeList.item(i); break; } } if (nameidElement != null) { nameidElement.setAttribute("NameQualifier", "TEST VALUE"); nameidElement.setAttribute("SPNameQualifier", "ANOTHER TEST VALUE"); } this.glidesaml2api.setCustomizedReqElemDOM(xmlRequestElement); } Related LinksRelated resources Steps to migrate from MultiSSOv1 to MultiSSOv2Customization best practices for ServiceNowUpgrade quickly and maintain platform health