Implementieren Sie eine Nonce

  • Freigeben Version: Xanadu
  • Aktualisiert 1. August 2024
  • 2 Minuten Lesedauer
  • Fügen Sie dem Authentifizierungsheader eine kryptografische Nonce hinzu, um sicherzustellen, dass sie nur einmal verwendet werden kann.

    • Erstellen Sie eine Systemeigenschaft mit dem Namen glide.authenticate.header.nonce_key, und legen Sie ihren Wert auf den Variablennamen fest, den Sie für die Nonce verwenden, z. B. NONCE oder NCE.
    • Erstellen Sie eine neue Tabelle mit der Bezeichnung u_authentication_nonce. Fügen Sie der Tabelle ein Feld mit der Bezeichnung u_nonce hinzu.
    • Gehe zu Systemeigenschaften > Installationsausgänge und erstellen Sie ein Element namens „ DigestSingleSignOnNonce“, das „ExternalAuthentication“ (glide.authenticate.external_property) überschreibt.
    • Fügen Sie dem Skriptteil des neu erstellten DigestSingleSignOnNonce den folgenden Code hinzu.
      
      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;
      	}
      };      
           
    • Sobald Sie Ihren neuen Installations-Exit gespeichert haben, wechseln Sie zum DigestSingleSignOn-Installations-Exit, und vergewissern Sie sich, dass Aktiv=falsch festgelegt ist.

    Ihre Instanz sollte jetzt für die Implementierung einer Nonce konfiguriert sein.