MultiSSOv2 でのカスタマイズのサポートSummary過剰なカスタマイズにより、技術的負債が蓄積され、アップグレードサイクルが長くなり、新しい機能の利用が妨げられる可能性があります。カスタマイズの需要を慎重に評価し、明確なビジネス価値があって需要を満たす代替手段がない場合にのみ、カスタマイズを採用するようにしましょう。カスタマイズの計画前に、次のドキュメントを確認してください。ServiceNow のカスタマイズのベストプラクティス MultiSSO に関しては、スクリプトを変更する前に、ID プロバイダーレコードの構成で同じ機能を実現できないかどうかを確認してください。以前のリリースではサポートされていなかった機能やカスタマイズが必要だった機能の一部が、すぐに利用可能 (OOTB) な状態でサポートされています。以下に例を示します。 HTTP-POST リダイレクトバインディングIDP が開始したシングルログアウト (SLO) (Rome リリース以降) MultiSSOv1 バージョンでは、カスタマイズのために SAML2_update1 および MultiSSO_SAML2_update1 スクリプトインクルードが変更されていました。これらの OOTB スクリプトへの変更は、アップグレードの際の課題になっていました。ServiceNow のアップグレードによってユーザーによるカスタマイズが上書きされることはありませんが、ServiceNow アップグレードモニターではスキップされたレコードとしてマークされます。アップグレード後のインスタンスに確実に移行するには、スキップされた変更を処理するための手動介入が必要でした。アップグレード時のこのような課題を回避するため、MultiSSOv2 バージョンでは OOTB 実装時のカスタマイズの対応方法が変更されています。この KB では、既存または新規のカスタマイズを MultiSSOv2 バージョンに組み込む方法の基本的な考え方を紹介します。Releaseこれらの手順は MultiSSOv2 バージョンで有効です。New York リリース以降で利用できます。 Instructionsアップグレード時の問題を軽減するため、MultiSSOv2 ではコアのシングルサインオンスクリプトインクルードが読み取り専用になっています。カスタマイズを適用するために、追加のスクリプトインクルードが用意されています。これらのカスタムスクリプトは、コアスクリプトを拡張します。これらの読み取り専用コアスクリプトインクルードで使用できるメソッドは、対応するカスタムスクリプトで上書きできます。カスタマイズの各種ユースケースに対応するため、OOTB スクリプトでは拡張ポイントとサポートメソッドも提供されます。注意:ServiceNow では、カスタマイズを目的として提供されたこれらのカスタムスクリプトに変更を加えることはありません。MultiSSOv2 および MultiSSOv2 でのスクリプトインクルードとインストレーションイグジットのマッピング 機能 タイプ カスタマイズのために変更するスクリプト v1 向け MultiSSOv2 バージョンでのOOTB 実装を使用する読み取り専用スクリプト カスタマイズのために OOTB 実装を上書きするスクリプト (MultiSSOv2) MultiSSO スクリプトインクルード SAML2_update1 SAML2_internal SAML2_custom MultiSSO_SAML2_Update1 MultiSSOv2_SAML2_internal MultiSSOv2_SAML2_custom インストレーションイグジット MultiSSO MultiSSOv2 MultiSSOLogout MultiSSOLogoutv2 電子署名 スクリプトインクルード ESignatureUtils ESignatureUtils SAML2_update1_esig SAML2_custom_esig 既存のカスタマイズを MultiSSOv1 バージョンから MultiSSOv2 に移行する際、顧客はカスタムスクリプトの OOTB 動作を上書きできます。 例えば、次のようになります。 MultiSSOv1 で、カスタマイズが SAML2_update1 スクリプトインクルードの特定のメソッド内で行われていた場合、MultiSSOv2 内の SAML2_internal スクリプトインクルード内で対応するメソッドを利用できます。カスタマイズのために同じメソッドを SAML2_custom スクリプトインクルードで上書きできます。 同様に、MultiSSOv1 のカスタマイズが MultiSSO_SAML2_Update1 スクリプトインクルードに含まれていた場合、MultiSSOv2 では対応する OOTB 実装を MultiSSOv2_SAML2_internal スクリプトインクルードで使用できます。カスタマイズのために、同じメソッドを SAML2_custom スクリプトインクルードで上書きできます。同じことが SAML2_update1_esig から SAML2_custom_esig スクリプトインクルードにも当てはまります。 SMAL2_internal で利用可能なメソッドの概要 Authn 要求オプションを上書きするための OOTB 認証オプション。 forceAuthn AuthnRequest で forceAuthn を設定する isPassive スクリプト内で AuthnRequest をパッシブとして設定する assertionConsumerServiceURL カスタム Authn 要求の構築中にスクリプトでアサーションコンシューマーサービス URL を設定する assertionConsumerServiceIndex カスタム Authn 要求の構築中にスクリプトでアサーションコンシューマーサービスインデックスを設定する providerName カスタム Authn 要求の構築中にスクリプトでプロバイダー名を設定する skipNavFrame 顧客がナビゲーションフレームなしで特定の URL またはパターンをレンダリングする場合 (ポータルなど)、フレームをスキップするオプションを設定できます。リレーステータスの生成中、nav_to は URL に追加されず、ページはナビゲーションフレームなしでレンダリングされます。 deepLink 顧客が特定の URL またはパターンのカスタムディープリンクまたは開始ページを設定する場合は、このパラメーターを設定できます。エンドユーザーは、ログインに成功すると常にディープリンクにリダイレクトされます。 SAML2_custom スクリプトインクルード内の SAML2_internal スクリプトインクルードで使用できる getAuthnOptions メソッドを上書きするスクリプトの例。これらの例は、デモンストレーション専用です。本番インスタンスに適用する前に、カスタマイズを十分にテストしてください。 getAuthnOptions : function() { var authGenerationOptions = {}; if(this.isTestSAMLConnection()){ authGenerationOptions.forceAuthn = true; } return authGenerationOptions; }, 下の例のように SAML2_custom 内で上書きします。 gs.include("PrototypeServer"); var SAML2_custom = Class.create(); SAML2_custom.prototype = Object.extend(new SAML2_internal(), { initialize:function() { SAML2_internal.prototype.initialize.call(this); }, getAuthnOptions : function() { var authGenerationOptions = {}; if(this.isTestSAMLConnection()) { authGenerationOptions.forceAuthn = true; } //Customization for forceAuthn authGenerationOptions.forceAuthn = true; return authGenerationOptions; }, type: 'SAML2_custom' }); OOB メソッドを使用したカスタマイズ:SAML 応答検証 カスタマイズのサポートに使用できる応答検証オプション (true/false)。 skip_responseissuer_checkskip_assertionissuer_checkskip_audiencerestriction_checkskip_onetimeuse_checkskip_proxyrestriction_checkskip_inresponseto_checkskip_sessionindex_checkskip_unknown_attribute_checksupport_httppost_login_only getValidationOptions: このメソッドは、SAML 応答検証のカスタマイズをサポートするためのものです。 SAML2_internal で使用できるメソッド getValidationOptions : function() { var responseValidationOptions = {}; return responseValidationOptions; }, 下の例のように SAML2_custom 内で上書きします。 gs.include("PrototypeServer"); var SAML2_custom = Class.create(); SAML2_custom.prototype = Object.extend(new SAML2_internal(), { initialize:function() { SAML2_internal.prototype.initialize.call(this); }, getValidationOptions : function() { var responseValidationOptions = {}; responseValidationOptions. skip_sessionindex_check=true; return responseValidationOptions; }, type: 'SAML2_custom' }); AuthN 要求のカスタマイズ customizeAuthnRequest: getAuthnOptions メソッドで使用できるオプションでは Authn 要求をカスタマイズできない場合、GlideXML API を使用してカスタマイズされた Authn 要求を構築し、このメソッドを使用して変更された要求を設定できます。 SAML2_internal で使用できるメソッド customizeAuthnRequest: function (xmlAuthnRequestElement) { return; }, 下の例のように SAML2_custom 内で上書きします。 スクリプトの例:要求 DOM を使用したスコープの作成 customizeAuthnRequest: function () { //Customization through Request DOM Element var xmlAuthnRequestElement = this.glidesaml2api.getGeneratedReqElemDOM(); var parentNameSpace = xmlAuthnRequestElement.getPrefix(); var scopingElement = GlideXMLUtil.newElement(xmlAuthnRequestElement, parentNameSpace + ":Scoping"); var idpListElement = GlideXMLUtil.newElement(scopingElement, parentNameSpace + ":IDPList"); var idpEntryElement = GlideXMLUtil.newElement(idpListElement, parentNameSpace + ":IDPEntry"); idpEntryElement.setAttribute('Name', 'uia.no'); idpEntryElement.setAttribute('ProviderID', this.getSSORecord().getValue('idp')); this.glidesaml2api.setCustomizedReqElemDOM(xmlAuthnRequestElement); //this is mandatory if the DOM is customized } Logout 要求のカスタマイズ customizeLogoutRequest: GlideXML API を使用して上記の例と同様にログアウト要求をカスタマイズし、変更された要求をこのメソッドによって設定します。次の例では、既に構築されているログアウト要求要素から取得した NameID ノードに 2 つの属性 (NameQualifier と SPNameQualifier) を追加します。 customizeLogoutRequest: function() { var xmlRequestElement = this.glidesaml2api.getGeneratedReqElemDOM(); var nodeList = xmlRequestElement.getChildNodes(); var nameidElement = null; for (var i = 0; i < nodeList.getLength(); i++) { if ("saml2:NameID".equalsIgnoreCase(nodeList.item(i).getNodeName())) { nameidElement = nodeList.item(i); break; } } if (nameidElement != null) { nameidElement.setAttribute("NameQualifier", "TEST VALUE"); nameidElement.setAttribute("SPNameQualifier", "ANOTHER TEST VALUE"); } this.glidesaml2api.setCustomizedReqElemDOM(xmlRequestElement); } Related Links関連リソース MultiSSOv1 から MultiSSOv2 に移行する手順ServiceNow のカスタマイズのベストプラクティス迅速なアップグレードによるプラットフォームの健全性の維持