---
sourceDocument: Brazil Platform security
sourceDocumentLink: https://www.servicenow.com/docs/r/platform-security

 Release :

    - brazil

ft:locale :

    - en-US

ft:publication_title :

    - Brazil Platform security

ft:clusterId :

    - psec

bundleId :

    - psec

workflow :

    - Platform


---

# Implement a nonce

# Implement a nonce {#ariaid-title1}

Release version: Brazil  
Updated September 10, 2026  
![](https://www.servicenow.com/docs/portal-asset/ico-clock) 2 minutes to read
Summarize  
![AI sparkle icon](https://servicenow.com/docs/portal-asset/ai-sparkle-icon) Summarized using AI  
This content was generated using new OpenAI-powered functionality. Results are provided on an as is basis and are not guaranteed to be accurate or complete.  

## Summary of Implement a nonce

This guide explains how to implement a cryptographic nonce in the authentication header for custom digest-based Single Sign-On (SSO) in ServiceNow.
The nonce ensures each authentication token is valid for only one use, enhancing security by preventing token replay attacks.
This implementation is designed for developers and SSO administrators with expertise in ServiceNow scripting and digest authentication protocols.
Show full answer Show less  

## Key Implementation Steps

* Create a system property **glide.authenticate.header.noncekey** and assign it the nonce variable name (e.g., NONCE).
* Create a custom table **uauthenticationnonce** with a field **unonce** to track used nonces.
* Define an installation exit named **DigestSingleSignOnNonce** to override **ExternalAuthentication** and implement nonce validation logic.
* Within the installation exit script:
  * Retrieve authentication headers or parameters for username, digest, and nonce.
  * Validate the digest by encrypting the username and nonce using a secret key and comparing it to the received digest.
  * Check if the nonce has already been processed to prevent reuse.
  * If validation passes, retrieve the user record based on the username field.
  * Insert the nonce into the **uauthenticationnonce** table to mark it as used.
* After saving the installation exit, ensure that the existing **DigestSingleSignOn** installation exit remains inactive (**Active=false**) to avoid conflicts.

## Why This Matters

By integrating a nonce into your custom digest-based SSO process, you strengthen authentication security by ensuring tokens cannot be reused. This reduces the risk of replay attacks and helps maintain the integrity of your ServiceNow instance's authentication mechanism.

## What to Expect

* Authentication requests will include a nonce that must be unique and unused.
* Tokens are validated against the nonce and digest to confirm authenticity.
* Reused nonces are rejected, preventing multiple uses of the same authentication token.
* Custom scripting and configuration are required, so developer involvement is necessary.  
Add a cryptographic nonce to the authentication header for custom digest-based Single Sign- On (SSO) to confirm that each authentication token is valid for one use only. This implementation requires
ServiceNow developer expertise.  
Implement a NONCE when your organization uses digest-based on Single Sign-On (SSO) authentication and requires that each authentication token can be used only once. This implementation requires developer expertise in ServiceNow scripting and knowledge of digest authentication protocols.  
Note:  
This topic is intended for developers and SSO administrators implementing custom authentication. For standard login configuration, see [Specify a login landing page](https://www.servicenow.com/docs/QztnFMDZ72K91cotYVjAdw "By default, users see their homepage on login. You can specify a different login landing page by using a system property or the content management system.").  
* Create a system property called glide.authenticate.header.nonce_key and set its value to whatever variable name you're using for the nonce, such as NONCE or NCE.
* Create a new table called `u_authentication_nonce`. Add a field to the table called `u_nonce`.
* Go to System PropertiesInstallation Exits and create an item called <kbd class="ph userinput">DigestSingleSignOnNonce</kbd> which overrides ExternalAuthentication (glide.authenticate.external_property).
* Add the following code to the script portion of the newly created DigestSingleSignOnNonce.


      gs.include("PrototypeServer");

      var DigestSingleSignOnNonce = Class.create();
      DigestSingleSignOnNonce.prototype = {
      	
      	process : function() {
      		
      		var headerKey = GlideProperties.get("glide.authenticate.header.key", "SM_USER");
      		var headerDigestKey = GlideProperties.get("glide.authenticate.header.encrypted_key", "DIGEST");
      		var headerNonceKey = GlideProperties.get("glide.authenticate.header.nonce_key", "NCE");
      		var fieldName = GlideProperties.get("glide.authenticate.header.value", "user_name");
      		var fkey = GlideProperties.get("glide.authenticate.secret_key");
      		
      		// Look in the Headers
      		var data = request.getHeader(headerKey);
      		var encdata = request.getHeader(headerDigestKey);
      		var nonce = request.getHeader(headerNonceKey);
      		
      		// If not, then check the URL Parameters
      		if (data == null || encdata == null || nonce == null) {
      			data = request.getParameter(headerKey);
      			encdata = request.getParameter(headerDigestKey);
      			nonce = request.getParameter(headerNonceKey);
      		}
      		
      		// then maybe its a cookie
      		if (data == null || encdata == null || nonce == null) {
      			var cookies = request.getCookies();
      			data = GlideCookieMan.getCookieValue(cookies, headerKey);
      			encdata = GlideCookieMan.getCookieValue(cookies, headerDigestKey);
      			nonce = GlideCookieMan.getCookieValue(cookies, headerNonceKey);
      		}
      		
      		// if found run encryption
      		if (data != null && encdata != null && nonce != null) {
      			try {
      				
      				// Replace all spaces with plus(+)'s, converted in url
      				encdata = encdata.replaceAll(' ', '+');
      				
      				// ----- Encrypt the username|nonce
      				var key = this.getDigest( data + "|" + nonce, fkey);
      				
      				// Check for match of received encoded data
      				// and your encoding of user name
      				if (encdata == key) {
      					var ugr = new GlideRecord("sys_user");
      					ugr.initialize();
      					if (!ugr.isValidField(fieldName)) {
      						GlideLog.warn("External authorization is set to use field: '"+ fieldName + "' which doesn't exist");
      						return "failed_missing_requirement";
      					}
      					ugr.addQuery(fieldName, data);
      					ugr.query();
      					if (!ugr.next()) {
      						var userLoad = GlideUser.getUser(data);
      						if (userLoad == null)
      							return "failed_authentication";
      						
      						ugr.initialize();
      						ugr.addQuery(fieldName, data);
      						ugr.query();
      						if (!ugr.next())
      							return "failed_authentication";
      						
      					}
      					
      					if (this.processNonce(nonce)){
      						var userName = ugr.getValue("user_name");
      						return userName;
      					}
      					else return "failed_missing_requirement";
      					}
      				else {
      					
      					return "failed_authentication";
      				}
      			} catch(e) {
      				gs.log(e);
      				return "failed_authentication";
      			}
      			// Encoded data didn't match recieved Encoded data
      		} else {
      			
      			return "failed_missing_requirement";
      		}
      	},
      	
      	getDigest : function( data, fkey ) {
      		try {
      			// default to something JDK 1.4 has
      			var MAC_ALG = "HmacSHA1";
      			return SncAuthentication.encode(data, fkey, MAC_ALG);
      			
      		} catch (e) {
      			gs.log(e.toString());
      			throw 'failed_missing_requirement';
      		}
      	} ,
      	
      	processNonce : function( sentNonce ) {
      		var ngr = new GlideRecord("u_authentication_nonce");
      		
      		ngr.addQuery("u_nonce", sentNonce);
      		ngr.query();
      		if (ngr.next()) {
      			gs.log("This SSO entry has already been processed! (Nonce: " + sentNonce + ")");
      			return false;
      		}
      		var ngrNew = new GlideRecord("u_authentication_nonce");
      		ngrNew.initialize();
      		ngrNew.u_nonce = sentNonce;
      		ngrNew.insert();
      		gs.log("Inserted new nonce: " + sentNonce);
      		return true;
      	}
      };      
           
* Once you've saved your new installation exit, go to the DigestSingleSignOn installation exit and make sure that it is set Active=false.
{#c_Implementation__ul_fdh_d3g_1p}

Your instance should now be configured to implement a nonce.

*[\>]: and then


