で電子署名を有効にする サービスポータル

  • リリースバージョン: Yokohama
  • 更新日 2025年01月30日
  • 所要時間:15分
  • サービスポータルで電子署名を設定して、ユーザーの承認からの再認証を要求できます。

    始める前に

    com.snc.integration.esig.window システムプロパティは、新しいウィンドウで SSO ログインを有効にするためにサポートされています。

    必要なロール:admin

    手順

    1. 電子署名 [com.glide.e_signature_approvals] プラグインで承認を有効にします。
    2. 次のように移動する。 システム定義 > e-Signature レジストリ.
    3. 電子署名を要求するテーブルをリストに追加します。

    タスクの結果

    電子署名を有効にすると、承認者はすべての要求を承認または拒否するためにパスワードを入力する必要があります。タッチ ID による認証はモバイル アプリで機能します。モバイル ウェブでは、承認者は引き続きパスワードを入力する必要があります。電子署名の設定の詳細については、「Approval with e-signature」を参照してください。

    新しいウィンドウで SSO ログインを有効にする

    承認に電子署名を使用する場合は、SSO 認証用に新しいウィンドウを開きます。

    始める前に

    セキュリティアサーションマークアップ言語 (SAML) ログインは、デスクトップサービスポータルでのみサポートされています。

    詳細については「電子署名 SSO ログイン KB 記事 (e-signature SSO login KB article)」を参照してください。

    必要なロール:admin

    手順

    1. spEsignatureCustom スクリプトを入力します。
      1. フィルターナビゲーターに sys_ui_script.list と入力します。
      2. [新規] を選択して、新しい UI スクリプトを作成します。
      3. UI スクリプトフォームで、[API 名] フィールドに spEsignatureCustom と入力します。
      4. [UI タイプ] フィールドで [モバイル/サービスポータル] を選択します。
      5. [スクリプト] フィールドに spEsignatureCustom スクリプトを貼り付けます。
      6. [送信] を選択します。
    2. spAuthCustom スクリプトを入力します。
      1. [新規] を選択して、同じ sys_ui_script.list テーブルで別の新しい UI スクリプトを作成します。
      2. UI スクリプトフォームで、[API 名] フィールドに spAuthCustom と入力します。
      3. [UI タイプ] フィールドで、[モバイル/サービスポータル] を選択します。
      4. [スクリプト] フィールドに spAuthCustom スクリプトを貼り付けます。
      5. [送信] を選択します。
    3. UI スクリプトを JS インクルードレコードに関連付けます。
      1. 次のように移動する。 サービスポータル > ポータル.
      2. 電子署名サポートを適用するサービスポータルを特定して、テーマを選択します。
      3. 関連リストで [JS インクルード] を選択します。
      4. [新規] を選択します。
      5. フォームのフィールドに入力します。
        表 : 1. JS インクルードフォーム
        フィールド 説明
        表示名 JS インクルードの名前。 spEsignatureCustom と入力してレコードを作成した spEsignatureCustom UI スクリプトに関連付けるか、 spAuthCustom と入力してレコードを作成した spAuthCustom に関連付けます。
        ソース JS インクルードレコードのソース。[UI スクリプト] を選択します。
        UI スクリプト JS インクルードレコードの UI スクリプトソース。作成しているレコードに応じて、spEsignatureCustom または spAuthCustom のいずれかを選択します。
        アプリケーション JS インクルードレコードのアプリケーション。デフォルトのアプリケーションは [グローバル] です。
        更新日時 レコードの最終更新時に表示されるフィールド。
        パッケージ JS インクルードパッケージを確立するフィールド。
      6. [送信] を選択します。

    タスクの結果

    電子署名を承認に使用すると、新しいウィンドウが開きます。

    spEsignatureCustom スクリプト

    [sys_ui_script.list スクリプト (sys_ui_script.list script )] フィールドに spEsignatureCustom スクリプトを貼り付けます。

    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 スクリプト

    [sys_ui_script.list スクリプト (sys_ui_script.list script)] フィールドに spAuthCustom スクリプトを貼り付けます。

    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 );});