Implement a nonce

concept australia Updated Sep 10, 2026 2 min read c_Implementation.md
Raw file servicenow.com

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.

  • 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 Properties > Installation Exits and create an item called DigestSingleSignOnNonce which overrides ExternalAuthentication (glide.authenticate.external_property).

  • Add the following code to the script portion of the newly created DigestSingleSignOnNonce.

    JavaScript
    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.

Your instance should now be configured to implement a nonce.

Search documentation
Search document titles and file paths on the australia branch