InfoPath Web ブラウザー フォームからの外部データ接続使用時における環境移行時の注意点(Windows 認証)

こんにちは、SharePoint サポートの森 健吾 (kenmori) です。今回の投降では、InfoPath Web ブラウザー フォームからの外部データ接続について注意点をご紹介します。

InfoPath のデータ接続では、SQL Server, Web サービス, XML ファイルなど様々な外部データに対する接続を標準機能で提供します。
しかしながら、標準設定でデータ接続を作成し、テスト環境で問題なかったとしても、本番環境に移行したタイミングでアクセスが拒否される状況に直面することが想定されます。

例えば、下記の様に本番環境でサーバー構成が変更されたとします。
・単一サーバーによるファーム構成から、複数サーバーによるファーム構成に変更した
・ホスト アドレスを使用していたが、FQDN やロード バランス用のアドレスに変更した
・Web アプリケーションの認証をクラシックベースからクレーム ベースに変更した

InfoPath は開発者ではないアプリ担当者の方に対しても、ノーコーディングで様々な機能を提供できる製品です。しかし、手軽に実装したものの、インフラ構成の変更によって、本番リリース前に上記のような構成変更によって生じる影響に気づき慌てることは多くあると思います。
InfoPath ブラウザー フォームでソリューションを作成することを計画する際には、本投稿をご参考にしていただけますと幸いです。

 

構成 1. クラシックベース Windows NTLM 認証の場合

(1) ダブルホップ

SharePoint ファームを単一サーバーによるファーム構成から、複数サーバーによるファーム構成に変更した場合、ダブルホップという NTLM の制限事項を考慮する必要があります。 
下記の図のように SharePoint が複数サーバー ファーム構成の場合、WFE サーバー上の Web サービスに対して NLB アドレスで接続する場合、サービス接続先が現在アクセスしている Web サーバーとは別サーバーに割り振られる場合があります。
その場合のみ、ダブルホップに該当する結果となります。この結果、ロードバランサーの動作によっては時折 HTTP 401 エラーによるサービス接続が失敗するという現象が発生します。

 

ダブルホップの問題は、ASPX ページが IIS サーバーとは別のサーバー上に存在するリソースを使用しようとしたときに発生します。この場合、Web ブラウザー (クライアント端末) から IIS ASPX ページへが 1 番目の "ホップ"、そこから別のサーバー (IIS, SQL Server, 外部サービス) へが 2 番目のホップです。
Web サービス接続では、SharePoint サーバーへの負荷分散用のアドレスを指定することになると思います。この際、上記の様にアクセスする先のサーバーが別サーバーに振り分けられダブルホップに該当する条件が生じます。

NTLM 認証では、1 番目のホップに対する認証情報を 2 番目のホップに対する認証をそのまま渡すことができません。結果的に 2 番目のホップに対しては匿名 (NTAUTHORITY\ANONYMOUS) アカウントの資格情報が使用されます。このアカウントはドメイン アカウントではないため、アクセスが拒否されるなどの現象が発生します。この動作は、NTLM 認証においては想定された動作となります。

 

タイトル : ASP ページの認証問題のトラブルシューティング
アドレス : https://msdn.microsoft.com/ja-jp/library/ms180891(v=vs.90).aspx
参考箇所 : ダブルホップの問題

 

対処策 ) hosts ファイルを使用する。

hosts ファイルに記載した IP アドレスは、DNS 設定よりも優先されます。
下記の様に各 SharePoint Server 上で、データ アクセス URL を必ず自サーバーに振り分けるよう制御することで、ダブルホップを防ぐことが可能です。

 

1. SharePoint Web フロント エンド サーバーに管理者でログインします。
2. 下記のフォルダにアクセスします。

C:\Windows\System32\drivers\etc

3. hosts ファイルをメモ帳などで開きます。
4. 下記のようなエントリを末尾に追加します。

127.0.0.1 sharepoint.com

なお、下記 (2) ループバックチェックの対処策は必ずセットで確認ください。

補足

もし運用要件により、InfoPath フォーム内に指定したデータ接続先とサイトへのアクセス先が異なる場合は下記の通り両方のホストを加えてください。
これは、InfoPath Forms Services がクロスドメインアクセス防止のため、アクセス先のホストを内部的に書き換えて要求する動作が備わっていることに起因します。

例)
データ接続先 URL : https://spswfe1
サイトの URL : https://portalsite

- hosts のエントリ
127.0.0.1 spswfe1 portalsite

対処策には他にも Kerberos 認証を使用する場合や、UDCX などを使用して偽装する方法もありますが、下記例に記載の通りハードルが高く。
最も手順や環境への影響が少なく即効性のある対処策をご紹介しています。

1) Kerberos 認証
設定変更がドメイン全体に影響する。

2) UDCX + 偽装、UDCX + Secure Store Service (グループ)
特定のユーザーに偽装する必要があるため、データ アクセス ユーザーによって判別する種類の処理を実行する場合、要件を満たさない。

3) UDCX + Secure Store Service (個別)
各ユーザーが Secure Store Service 上に自身のパスワードを管理しないといけない。

(2) ループバックチェック

テスト環境では、ホスト アドレスを使用していたが、本番環境においては FQDN やホストヘッダーあるいは、負荷分散用のアドレスに変更した場合には、ループバックチェックも併せて考慮する必要があります。
サーバーから、ローカルの Web サイト上のコンテンツにアクセスする際に、ホスト名以外のアドレス (例. 完全修飾ドメイン名 (FQDN),カスタム ホスト ヘッダー, ロード バランサーのアドレス) を使用すると、HTTP 401 エラーが発生します。

InfoPath の Web サービス接続は、サーバー端末からの Web サーバー アクセスに該当し、場合によっては自端末へのアクセスとなり、ループバック チェックに該当する可能性もあります。
ループバックチェックの設定変更は下記サポート技術情報に記載されている方法1. 方法 2. の通り、レジストリの設定を変更後再起動することで実施できます。

タイトル : 統合認証を使用して、IIS 5.1 または以降のバージョンでホストされている Web サイトを参照するとエラー 401.1 が表示されます。
アドレス : https://support.microsoft.com/kb/896861

構成 2. クレーム ベース Windows 認証の場合

クラシックベース認証で Windows 認証を構築した場合、SharePoint サーバーは ASP.NET 偽装の動作に基づき、Windows 資格情報を使用してユーザーが Web アプリケーションに対して認証後は、HTTP 要求スレッドはブラウザーにログインしたユーザーの実行権限で偽装されました。
そのため、Kerberos による委任を構築している前提があれば、現在の資格情報であるスレッド実行ユーザー アカウントを使用して第 2 のサーバーにアクセスすることができました。

しかし、クレームベース認証で Windows 認証を構築した際、Windows 資格情報を使用してユーザーが Web アプリケーションに対して認証後は、HTTP 要求スレッドは ClaimsIdentity として偽装され、スレッドの実行ユーザーは匿名ユーザーとなります。
ブラウザーでアクセスしたユーザーではなく匿名ユーザーとして HTTP 要求スレッドが動作するため、第 2 のサーバーにそのままアクセスする権限を獲得することはできません。

つまり、注意点としてクラシックベース NTLM では条件さえ整えば第 2 のサーバーに対してそのままアクセス可能でしたが、クレームベースでは完全に不可となります。詳細は過去の投稿をご確認ください。

タイトル : SharePoint クラシック ベースからクレーム ベースのWindows 認証に置き換えた際の注意点
アドレス: https://blogs.technet.com/b/sharepoint_support/archive/2013/11/07/sharepoint-windows.aspx
参考箇所 : 2. Windows ユーザー トークンに関連したカスタマイズに対する影響

 

対処策 ) UDCX を使用した対処

クレームベース認証においては、画期的な方法はありません。UDCX を使用してアクセスを偽装することが最も近道です。
もしアクセスしたユーザーでサービス側の処理を実行したいという要望であれば、上記 SharePoint クラシック ベースからクレーム ベースのWindows 認証に置き換えた際の注意点 で紹介したように、C2WTS を使用して Windows トークンを取得して偽装アクセスを実施する処理を VSTA コードで実装し、管理者承認フォーム テンプレートとしてファームに発行するしかありません。
この投稿では、その方法は割愛します。

下記対処策の手順では、SharePoint が公開している Web サービスである UserProfileService.GetUserProfileByName メソッド実行を例に記載しております。
クレームベースであっても、ネットワーク構成上自サーバーに FQDN アドレスなどでアクセスが生じる場合、(2) ループバック チェックの対処が必要となりますので、併せてご確認ください。

1. データ接続ライブラリの準備
1-1. ブラウザーで SharePoint サイトにアクセスします。
1-2. [サイトの操作] - [その他のオプション] をクリックします。
1-3. "フィルター" にて "ライブラリ" を選択し、"データ接続ライブラリ" を選択して任意のライブラリ名 (例. DataConLib) を指定して [作成] をクリックします。
1-4. 作成したデータ接続ライブラリのアドレスを控えておきます。
例)
 https://sharepoint/sites/site/DataConLib/

- 補足
すでにサイト内にデータ接続ライブラリが存在する場合は、上記手順は必要ございません。

2. InfoPath のデータ接続の編集
2-1. InfoPath Designer にて該当フォーム テンプレートを開きます。
2-2. InfoPath フォームのメニューの "データ" タブの [データ接続] をクリックします。
2-3. GetUserProfileByName を呼び出すデータ接続を選択して [変更] をクリックします。
2-4. [次へ] を 4 回クリックし、"フォームを開くとき自動的にデータを取得する" のチェックを外して [完了] をクリックします。
2-5. GetUserProfileByName を呼び出すデータ接続を選択して [接続ファイルに変換] をクリックします。
2-6. "データ接続の変換" ダイアログにて、参照ボタン等を使用して以下の URL をテキストに記載します。
例)
 https://sharepoint/sites/site/DataConLib/GetUserProfileByName.udcx
2-7. [OK] をクリックします。
2-8. [閉じる] をクリックします。

3. UDCX の構成
UDCX を構成する場合、対処策 (1) 明示的にバックエンド サービスに接続するアカウント名およびパスワードを指定する方法と、対処策 (2) Secure Store Service を使用する方法が考えられます。
以下に 2 つの方法を記載させていただきますので、ご確認くださいますようお願いいたします。

対処策 1) 明示的にバックエンド サービスに接続するアカウント名およびパスワードを指定する方法
3-(1)-1. 該当の InfoPath フォームで使用しているデータ接続ファイル (例. GetUserProfileByName) を、データ接続ライブラリからダウンロードします。
3-(2)-2. 上記手順で保存したファイル (GetUserProfileByName.udcx) をテキスト エディタで開きます。
3-(2)-3. 以下の該当箇所を検索し変更します。
- 変更前
<!--udc:Authentication><udc:SSO AppId='' CredentialType='' /></udc:Authentication-->

  ↓

- 変更後
<udc:Authentication>
  <udc:UseExplicit CredentialType="NTLM">
    <udc:UserId>DOMAIN\Administrator</udc:UserId>
    <udc:Password>password</udc:Password>
  </udc:UseExplicit>
</udc:Authentication>

3-(1)-4. 上記ファイル (GetUserProfileByName.udcx) を保存した後、再度、SharePoint サイトの データ接続ライブラリ (date01) にアクセスします。

3-(1)-5. [新しいアイテム] - [ファイルの選択] から、上記手順 4-(2)-2-3 にて変更したデータ接続ファイル (GetUserProfileByName.udcx) を選択して [OK] をクリックします。既存のファイルが上書きされます。

タイトル : ユニバーサル データ接続 v2.0 リファレンスおよびスキーマ
アドレス : https://msdn.microsoft.com/ja-jp/library/ms772017(v=office.14).aspx

平文で UDCX ファイルにパスワードが記録されることにセキュリティ上の懸念がある場合は対処策 2) を検討ください。

 (補足)
この設定を有効化するためには、SharePoint サーバーの全体管理画面にて [アプリケーションの全般設定] - [InfoPath Forms Services の構成] 画面に遷移し、"ユーザー フォーム テンプレートでデータ接続ファイルに含まれる認証情報を使用可能にする" にチェックを入れるよう構成する必要があります。

 

対処策 2) Secure Store Service を使用する方法

以降の手順では、SharePoint 側に発行したInfoPath フォームにて、該当ユーザーに紐づく部署名を取得できるようするため、Secure Store Service の構成を行います。

3-(2)-1. SharePoint のサーバーの全体管理サイトにアクセスします。

3-(2)-2. [アプリケーション構成の管理] をクリックし、[サービス アプリケーションの管理] をクリックします。

3-(2)-3. サービスの一覧から [Secure Store Service] をクリックします。

3-(2)-4. "Secure Store Service" ページで、[新規作成] をクリックします。

- 補足
初めて Secure Store Service を構成する場合には、新しいキーの生成が必要になります。
新しいキーの生成は、[新しいキーの生成] をクリックし任意のパスフレーズを入力して [OK] をクリックします。

 

3-(2)-5. "Secure Store のターゲット アプリケーションを新規に作成します" ページにて、以下を入力し [次へ] をクリックします。

  ターゲット アプリケーションID : 任意 (例 : TestSSSGroup) (ここで設定した ID 名は 手順 4-(2)-12 で使用します)
  表示名 : 任意 (例 : TestSSSGroup)
  連絡先の電子メール : 任意のメールアドレス
  ターゲット アプリケーションの種類 : グループ

3-(2)-6. 既定で "Windows ユーザー名" と "Windows パスワード" と表示されるページにて [次へ] をクリックします。
3-(2)-7. "ターゲット アプリケーションの管理者" に、任意の管理者アカウントを設定します。
3-(2)-8. "メンバー" に、ターゲット アプリケーション用に定義される資格情報にマップされるユーザーのグループを設定します。(例 : Domain Users) 4-(2)-1-9. 作成したターゲット アプリケーション ID (TestSSSGroup) を右クリックし、[資格情報の設定] をクリックします。
3-(2)-9. Secure Store のターゲットアプリケーションの資格情報の設定 ("Windows ユーザー名"、"Windows パスワード"、"Windows パスワード の確認") をおこない、[OK] をクリックします。

※ SharePoint への Web サービス接続を想定しておりますので、ここで設定する Windows ユーザー名は、管理者権限以上 (例 : システムアカウント) のユーザーを設定ください。

3-(2)-10. 該当の InfoPath フォームで使用しているデータ接続ファイル (GetUserProfileByName) を、データ接続ライブラリからダウンロードします。
3-(2)-11. 上記手順で保存したファイル (GetUserProfileByName.udcx) をテキスト エディタで開きます。
3-(2)-12. 以下の該当箇所を検索し変更します。(上記手順 4-(2)-1-5 で作成したSecure Store のターゲット アプリケーションID (TestSSSGroup) を設定します)

- 該当箇所
<!--udc:Authentication><udc:SSO AppId='' CredentialType='' /></udc:Authentication-->

- 変更前
<!--udc:Authentication><udc:SSO AppId='' CredentialType='' /></udc:Authentication-->

  ↓

- 変更後
<udc:Authentication>
  <udc:SSO AppId='TestSSSGroup' CredentialType='NTLM'/>
</udc:Authentication>

3-(2)-13. 上記ファイル (GetUserProfileByName.udcx) を保存した後、再度、SharePoint サイトの データ接続ライブラリ (date01) にアクセスします。
3-(2)-14. [新しいアイテム] - [ファイルの選択] から、上記手順 4-(2)-2-3 にて変更したデータ接続ファイル (GetUserProfileByName.udcx) を選択して [OK] をクリックします。既存のファイルが上書きされます。

補足

本投稿の本筋とは異なりますが、上記の例で記載した GetUserProfileByName メソッドでは、引数を省略すると現在のユーザーのプロファイル情報を取得します。
この仕組みを使用する場合は多いですが、上記 UDCX を使用した方法だとある特定の偽装ユーザーでアクセスする動作に変更されます。

ユーザー名を指定したい場合は、下記のような動作規則を組み込むことで対処可能です。

1. リボン メニューより [データ] - [フォームの読み込み] をクリックします。
2. "ルール" ペインにて [新規作成] - [動作] をクリックします。
3. [追加] - [フィールドの値を設定する] をクリックします。
4. "フィールド" にて右のボタンをクリックします。
5. GetUserProfileByName (セカンダリ) を選択します。
6. myFields - queryFields - tns:GetuserProfileByName - AccountName を選択します。
7. "値" にて [fx] ボタンをクリックします。
8. 以下の式を指定します。

クラシックベースの場合 (DOMAIN にはお客様環境のドメインを指定ください。)

  concat("DOMAIN\", userName())

クレーム ベースの場合

  userName()

9. [OK] をクリックします。
10. [OK] をクリックします。
11. "動作規則" にて [追加] - [データのクエリを送信する] をクリックします。
12. GetUserProfileByName を指定して [OK] をクリックします。

今回の投稿は以上になります。