---
sourceDocument: Australia ServiceNow AI Platform user interface
sourceDocumentLink: https://servicenow-prod.fluidtopics.net/r/pt-BR/platform-user-interface

 Release :

    - australia

ft:locale :

    - pt-BR

ft:publication_title :

    - Australia ServiceNow AI Platform user interface

ft:clusterId :

    - platux

bundleId :

    - platux

workflow :

    - Platform


---

# Enable e-signature for Service Portal

# Enable e-signature for Service Portal {#ariaid-title1}

* Versão de lançamento: Australia
* 
* Atualizado 12 de mar. de 2026
* 
* ![](https://www.servicenow.com/docs/portal-asset/ico-clock) 5 min. de leitura

You can configure e-signature in Service Portal to require
re-authentication from approving users.

## Antes de Iniciar

The com.snc.integration.esig.window system property is
supported to enable SSO login in a new window.
Role required: admin

## Procedimento

1. Activate the Approvals with e-Signature \[com.glide.e_signature_approvals\] plugin.
2. Navigate to System Definitione-Signature Registry.
3. Add any tables you want to require an e-signature for to the list.

## Resultado

With e-signature enabled, approvers are required to provide a password to approve or reject any requests. Authentication with touch ID works in the mobile app. On the mobile web, approvers are still required to enter a password. For more information on configuring e-signature, see [Approval with e-signature](https://www.servicenow.com/docs/access?context=approval-with-e-signature&version=australia&pubname=australia-build-workflows&ft:locale=en-US).

## Enable SSO login in a new window {#ariaid-title2}

Open a new window for SSO authentication when using e-Signature for
approvals.

### Antes de Iniciar

Security Assertion Markup Language (SAML) login is only supported on the desktop Service Portal.

For additional information, see the [e-signature SSO login KB article](https://support.servicenow.com/kb?id=kb_article_view&sys_kb_id=2dca1fe8db49a010190b1ea668961999).

Role required: admin

### Procedimento

1. Enter the spEsignatureCustom script.
   1. Enter <kbd class="ph userinput">sys_ui_script.list</kbd> in the Filter navigator.
   2. Select New, and create a new UI script.
   3. On the UI Script form, enter <kbd class="ph userinput">spEsignatureCustom</kbd> in the API Name field.
   4. In the UI Type field, select Mobile/Service Portal.
   5. Paste the [spEsignatureCustom script](https://servicenow-prod.fluidtopics.net/hmzM7d3nAIraunXVxnN8tQ#spEsignatureCustom-script "Paste the spEsignatureCustom script in the sys_ui_script.list script field.") in the Script field.
   6. Select Submit.
   {#enable-sso-login__substeps_kzw_jyb_bqb}
2. Enter the spAuthCustom script.
   1. In the same <kbd class="ph userinput">sys_ui_script.list</kbd> table, create another new UI script by selecting New.
   2. On the UI Script form, enter <kbd class="ph userinput">spAuthCustom</kbd> in the API Name field.
   3. In the UI Type field, select Mobile/Service Portal.
   4. Paste the [spAuthCustom
      script](https://servicenow-prod.fluidtopics.net/hmzM7d3nAIraunXVxnN8tQ#spAuthCustom-script "Paste the spAuthCustom script in the sys_ui_script.list script field.") in the Script field.
   5. Select Submit.
   {#enable-sso-login__substeps_fb3_syb_bqb}
3. Associate the UI scripts to the JS Include record.
   1. Navigate to Service PortalPortals.
   2. Identify the Service Portal you want to apply the esignature support to and select the Theme.
   3. In the related lists, select JS Includes.
   4. Select New.
   5. On the form, fill in the fields.  
      {#enable-sso-login__table_rhs_czb_bqb__entry__2}

      | Field | Description |
      |-|-|
      | Display name | Name for your JS Include. Enter <kbd class="ph userinput">spEsignatureCustom</kbd> and associate the record with the spEsignatureCustom UI script you created, or enter <kbd class="ph userinput">spAuthCustom</kbd> and associate the record with spAuthCustom you created. |
      | Source | Source for your JS Include record. Select UI Script. |
      | UI script | UI script source for your JS Include record. Select either spEsignatureCustom or spAuthCustom depending on the record you're creating. |
      | Application | Application for your JS Include record. The default application is Global. |
      | Updated | Field displaying when the record was last updated. |
      | Package | Field that establishes the JS Include package. |
      [Tabela 1. JS Include form]

      {#enable-sso-login__table_rhs_czb_bqb}
   6. Select Submit.
   {#enable-sso-login__substeps_xrw_zyb_bqb}

### Resultado

A new window opens when you use E-Signature for approvals.

## spEsignatureCustom script {#ariaid-title3}

Paste the spEsignatureCustom script in the sys_ui_script.list script field.

    angular.module('sn.$sp').provider('spEsignature', function() {
    	'use strict';

    	this.$get = function spEsignature($q, $http, $window, urlTools, xmlUtil) {
    		var w = window;
    		var esignOW;
    		var windowWidth;
    		var windowHeight;
    		var redirectURL;

    		function isWindowChosen() {
    			var postParams = {
    				sysparm_scope: 'global',
    				sysparm_processor: 'ESignatureAuthUtils',
    				sysparm_name: 'isWindowChosen'
    			};
    			return $http({
    				method: 'POST',
    				url: '/xmlhttp.do',
    				data: urlTools.encodeURIParameters(postParams),
    				headers: {
    					'Content-Type': 'application/x-www-form-urlencoded'
    				},
    				transformResponse: function(response) {
    					return xmlUtil.getDataFromXml(response);
    				}
    			}).then(
    				function(response) {
    					var data = response.data ? response.data[0] : {};
    					return data.answer ===  'true'
    				},
    				function(response) {
    					// Handling failure case.
    					switch (response.status) {
    						default:
    						case 404:
    							return false;
    					}
    				});
    		}

    		function initiateEsignature() {
    			var postParams = {
    				sysparm_scope: 'global',
    				sysparm_processor: 'ESignatureAuthUtils',
    				sysparm_name: 'fetchAuthDetails'
    			}
    			return $http({
    				method: 'POST',
    				url: '/xmlhttp.do',
    				data: urlTools.encodeURIParameters(postParams),
    				headers: {
    					'Content-Type': 'application/x-www-form-urlencoded'
    				},
    				transformResponse: function(response) {
    					return xmlUtil.getDataFromXml(response, 'result');
    				}
    			}).then(
    				function(response) {
    					var data = response.data ? response.data[0] : {};
    					process(data);
    				});
    		}

    		function process(data) {
    			var shouldLogoutFirst = data.logoutFirst === 'true';
    			w['windowHeight'] = data.popup_window_height;
    			w['windowWidth'] = data.popup_window_width;
    			w['redirectURL'] = data.loginURL;
    			if (shouldLogoutFirst)
    				openEsignatureWindow(data.logoutURL);
    			else
    				authenticate();
    		}

    		function openEsignatureWindow(url) {
    			w['esignOW'] = window.open(url, 'esignatureAuthentication',
    				'height='+w['windowHeight']+',width='+w['windowWidth']+',top=100,left=100,toolbar=0,location=0,menubar=0');
    		}

    		w['authenticate'] = function(){
    			if(w['redirectURL']){
    				if(w['esignOW']) //when we signed out previously, a window is already opened. reuse it.
    					w['esignOW'].location.href = w['redirectURL'];
    				else
    					openEsignatureWindow(w['redirectURL']);
    			}
    		};

    		w['evaluateRedirect'] = function(msg) {
    			w['esignOW'].close();
    			if (msg == "saml2 login complete") {
    				$window.onReauthenticationComplete(msg);
    			}
    		};

    		return {
    			isWindowChosen: isWindowChosen,
    			initiateEsignature: initiateEsignature
    		};

    	};
    });

## spAuthCustom script {#ariaid-title4}

Paste the spAuthCustom script in the sys_ui_script.list script field.

    angular.module('sn.$sp').factory('spAuthModal', function($q, spModal, i18n, $http, spAuthentication, glideUserSession, cabrillo, $cookies, $window, spUtil, $uibModal, spEsignature) {
    	"use strict";

    	function _showAuthenticationModal(requestParams, username, userSysId) {
    		var currentUser;
    		var deferred = $q.defer();
    		glideUserSession.loadCurrentUser({reload: true}).then(function(user) {
    			if (!user) {
    				deferred.reject({
    					error: {
    						status: 'ANONYMOUS',
    						message: i18n.getMessage('Not logged in')
    					}
    				});
    				return;
    			}
    			currentUser = user;
    			var serializedUser = {
    				sysId: currentUser.userID,
    				userName: currentUser.userName,
    				firstName: currentUser.firstName,
    				lastName: currentUser.lastName
    			};

    			// hand off to native clients
    			if (cabrillo.isNative()) {
    				cabrillo.auth.reauthenticate(currentUser).then(function() {
    					deferred.resolve(serializedUser);
    				}, function(error) {
    					if (error && error.status) {
    						deferred.reject({
    							error: error
    						});
    					}
    					//TODO: Handle rejection a little more gracefully
    					deferred.reject();
    				});
    				return;
    			}

    			var loginMethod = currentUser.$private.loginMethod;
    			if (!loginMethod) {
    				// As we were unable to determine the login method via the HTTP session, trying to get glide_sso_id cookie which is set in case of multisso login
    				var providerSysId = $cookies.get('glide_sso_id');
    				loginMethod = providerSysId ? 'multisso' : 'db';
    			}

    			if (loginMethod === 'saml' || loginMethod === 'oidc' || loginMethod === 'multisso') {
    				spEsignature.isWindowChosen().then(function(result) {
    					var modal;
    					if (!spUtil.isMobile() && loginMethod !== 'oidc' && result === true) {
    						// If enabled, Opening a new window for desktop saml login
    						spEsignature.initiateEsignature();
    					} else {
    						glideUserSession.getSsoReauthenticationUrl().then(function(url) {
    							requestParams.externalLoginURL = url;
    							openExternalAuthModal(requestParams).then(function(m) {
    								modal = m;
    							});
    						});
    					}
    					$window.onReauthenticationComplete = function(result) {
    						deferred.resolve(serializedUser);
    						if (modal)
    							modal.close();
    					};
    				});
    			} else {
    				spModal.open({
    					title:i18n.getMessage("Approver authentication"),
    					message:i18n.getMessage("Additional authentication is required, enter your usename and password to continue."),
    					footerStyle: {border: 'none', 'padding-top': 0},
    					widget: 'simpleloginui',
    					widgetInput: {},
    					shared: requestParams,
    					onSubmit: function() {
    						return onLoginModalSubmit(requestParams, username);
    					}
    				}).then(function(confirm) {
    					if (confirm.label == i18n.getMessage("OK")) {
    						deferred.resolve(serializedUser);
    					} else {
    						deferred.reject();
    					}
    				});
    			}
    		});

    		return deferred.promise;
    	}

    	function onLoginModalSubmit(requestParams, username) {
    		//(1) call login service to verify auth
    		//(2) verify same user
    		return $q(function(resolve, reject) {
    			var errorMessage = null;

    			if(!requestParams.username || requestParams.username.trim() === "" ||
    					!requestParams.password || requestParams.password.trim() === "") {
    				errorMessage = i18n.getMessage("User name or password invalid");
    			} else if(requestParams.username !== username) {
    				errorMessage = i18n.getMessage("Attempted to authenticate as a different user");
    			}

    			if(!errorMessage || errorMessage === "") {
    				spAuthentication.validateCreds(requestParams.username, requestParams.password).then(function(res) {
    					resolve({status: res.success, errorMessage: res.message});
    				});
    			} else {
    				resolve({status: !errorMessage || errorMessage === "", errorMessage: errorMessage});
    			}
    		});

    	}

    	function openExternalAuthModal(requestParams) {
    		var deferred = $q.defer();

    		var options = {
    			title: i18n.getMessage("Approver authentication"),
    			message: '',
    			messageOnly: false,
    			errorMessage: '',
    			input: false,
    			label: '',
    			size: 'lg',
    			value: '',
    			required: false,
    			footerStyle: {border: 'none', 'padding-top': 0},
    			values: false,
    			onSubmit: null,
    			widget: 'simpleloginui',
    			widgetInput: {},
    			shared: requestParams,
    			buttons: [{label: i18n.getMessage('Cancel'), cancel:true}]
    		};

    		var widgetURL = spUtil.getWidgetURL(options.widget);
    		$http.post(widgetURL, options.widgetInput).success(function(response) {
    			options.widget = response.result;
    			options.widget.options.shared = options.shared;
    			var modal = $uibModal.open({
    				templateUrl:'sp-modal.html',
    				controller: spModalCtrl,
    				size: options.size,
    				resolve: {
    					options: function() {
    						return options;
    					}
    				}
    			});

    			deferred.resolve(modal);
    		});
    		
    		return deferred.promise;
    	}

    	function spModalCtrl($scope, options) {
    		$scope.options = options;
    		$scope.form = {};

    		$scope.buttonClicked = function(button){
    			if (button.cancel) {
    				$scope.$dismiss();
    				return;
    			}
    		}
    	}

    	return {
    		prompt: _showAuthenticationModal
    	}
    }).decorator("spAuthModal", function($delegate) { return( $delegate );});


