에 대해 전자 서명 사용 서비스 포털

  • 릴리스 버전: Xanadu
  • 업데이트 날짜 2024년 08월 01일
  • 소요 시간: 15분
  • 승인하는 사용자의 재인증을 요구하도록 에서 전자 서명 서비스 포털 을 구성할 수 있습니다.

    시작하기 전에

    새 창에서 SSO 로그인을 com.snc.integration.esig.window 사용하도록 시스템 속성이 지원됩니다.

    필요한 역할: admin

    프로시저

    1. 전자 서명으로 승인 [com.glide.e_signature_approvals] 플러그인을 활성화합니다.
    2. 다음으로 이동 시스템 정의 > 전자 서명 레지스트리.
    3. 전자 서명이 필요한 테이블을 목록에 추가합니다.

    결과

    전자 서명을 사용할 경우 승인자는 요청을 승인하거나 거부하기 위해 암호를 제공해야 합니다. Touch ID를 사용한 인증은 모바일 앱에서 작동합니다. 모바일 웹에서 승인자는 여전히 암호를 입력해야 합니다. 전자 서명 구성에 대한 자세한 내용은 을 참조하십시오 Approval with e-signature.

    새 창에서 SSO 로그인 사용

    승인을 위해 전자 서명을 사용할 때 SSO 인증을 위한 새 창을 여십시오.

    시작하기 전에

    SAML(Security Assertion Markup Language) 로그인은 데스크톱 서비스 포털에서만 지원됩니다.

    자세한 내용은 전자 서명 SSO 로그인 KB 문서를 참조하십시오.

    필요한 역할: 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 스크립트

    spEsignatureCustom 스크립트를 sys_ui_script.list 스크립트 필드에 붙여넣습니다.

    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 스크립트

    spAuthCustom 스크립트를 sys_ui_script.list 스크립트 필드에 붙여넣습니다.

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