Implement a nonce
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 calledu_nonce. -
Go to System Properties > Installation Exits and create an item called
DigestSingleSignOnNoncewhich overrides ExternalAuthentication (glide.authenticate.external_property). -
Add the following code to the script portion of the newly created DigestSingleSignOnNonce.
JavaScriptgs.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.
---
title: Implement a nonce
description: 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.
locale: en-US
canonical_url: https://www.servicenow.com/docs/r/australia/platform-security/authentication/c\_Implementation.html
release: australia
product: Authentication
classification: authentication
topic_type: concept
last_updated: "2026-09-10"
reading_time_minutes: 2
breadcrumb: [Implement a nonce, Local authentication, Authentication, Access Management]
---
# Implement a nonce
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://raw.githubusercontent.com/ServiceNow/ServiceNowDocs/australia/markdown/australia/platform-security/authentication/t_SpecifyingALoginLandingPage.md).
- 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.
```
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.
| title | Implement a nonce |
| description | 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. |
| locale | en-US |
| canonical_url | https://www.servicenow.com/docs/r/australia/platform-security/authentication/c\_Implementation.html |
| release | australia |
| product | Authentication |
| classification | authentication |
| topic_type | concept |
| last_updated | 2026-09-10 |
| reading_time_minutes | 2 |
| breadcrumb | Implement a nonceLocal authenticationAuthenticationAccess Management |