Windows Server 2012 以降の DC で、SharePoint のユーザーの権限が適切に判断されない (External Token 関連)

こんにちは SharePoint サポートの森 健吾 (kenmori) です。

今回の投稿では、Windows Server 2012 ドメイン コントローラーを導入した際に、Windows Server 2008 または2008 R2 上で動作する SharePoint Server 2013、SharePoint 2010 において、ユーザーの権限の確認が適切に行えなくなる現象とその対処策をご紹介いたします。
この問題の影響により、セキュリティ グループ経由で権限を付与している場合に、セキュリティ グループに所属しているユーザーに内部処理で権限がないと判断されることがあります。
ただし、通常 SharePoint にログインして使用する際には、影響を受けることはほとんどありません。

想定される影響範囲

この影響により、下記のような現象が発生します。

・対象アイテムに権限のあるはずのユーザーに対して、通知メールが送信されない。
・ワークフローの処理でアクセス拒否が発生する。(ワークフロー テンプレートの作成者に偽装しても処理が実行できない)
・カスタム ソリューションにおいて、偽装 (SPUserToken 使用) 後の処理でアクセス拒否が発生する。

・サイトの権限画面などで [権限の確認] をクリックし、ユーザー権限を確認しても権限がないと判断される。
・カスタム ソリューションにおいて DoesUserHavePermissions メソッドの実行で権限がないと判断される。

原因

本現象は External Token の更新処理に問題が発生することに起因して発生します。

External Token とは

External Token は、主にユーザーがログインしていない状況において、指定されたユーザーに偽装・権限確認などを行うために使用されるトークンです。
ユーザーが対話的に SharePoint Server にログインした際に生成される認証情報には、ユーザーを識別する情報およびセキュリティ グループへの所属情報などがすでに含まれています。ブラウザーでログインした際には、これらの認証情報を使用してリソースへのアクセスの可否を決定しています。
さらに SharePoint では、バックグラウンド サービスなどの処理において、ユーザーがログインしていない状況においても、偽装したアクセスを可能とする必要があり、アクセス権の判断のために必要な情報を扱う必要があります。

SharePoint ではユーザー偽装 (*1) を実現するために、External Token と呼ばれるトークン (*2) をキャッシュしています。この値は、コンテンツ データベース内の UserInfo テーブルに tp_ExternalToken というバイナリ値として保存され、取得した時間 (tp_ExternalTokenLastUpdated) より、既定では24 時間 (*3) の間キャッシュされます。

External Token 更新処理について

External Token の更新処理については、トークンの有効期限切れになった際に、下記のような診断ログを出力して、更新処理を実行します。

MM/DD/YYYY hh:mm:ss.ff w3wp.exe (0x1234)                               0x5678  SharePoint Foundation                 General                         72nz    Medium          Videntityinfo::isFreshToken reported failure.        <CORRELATIONID>

この更新処理は、ユーザー ログイン時とユーザー非ログイン時で大きく処理が異なります。

ユーザーがログインしている状況であれば、ログイン時にすでに取得しているスレッド トークンまたはクレームをもとに、必要な情報やセキュリティ グループへの所属情報を抜き出して、External Token を作成して更新します。このため SharePoint Server に対話的にログインしている状況で行われる External Token 生成処理は全く問題ありません。

しかし、ユーザーが対話的にログインしていない (偽装状態) であれば、SharePoint はドメイン コントローラー サーバーに問い合わせ、偽装されたユーザーが所属するセキュリティ グループ一覧を作りこむ動作が実装されております。

この際に、Windows Server 2012 が追加した SID を旧 Windows Server がクライアント側で適切に変換できず内部エラーが発生します。

SharePoint ではこのエラーが診断ログに出力されないため、冒頭に記載した現象が発生して初めて気づくことになります。

補足事項

*1) ユーザーの偽装

本投稿で記載した内容に最も準じる公開情報は下記となります。

タイトル : 偽装
アドレス : https://msdn.microsoft.com/ja-jp/library/office/aa543158(v=office.14).aspx

*2) ExternalToken 値の形式

ExternalToken バイナリ値は、大枠として下記のような形式でバイナリ値を構成しております。現象発生時には、このうちユーザーが所属しているセキュリティ グループの一覧が抜け落ちる形となります。そのため、SQL Server Management Studio などで UserInfo テーブルの tp_ExternalToken 列の BLOB 値を確認すると、現象発生時 (権限がない) のものは現象発生 (権限がある) していない時のものよりも著しく短くなります。

タイトル : 2.2.3.2 External Group Token
アドレス : https://msdn.microsoft.com/en-us/library/hh647479(v=office.12).aspx

*3) ExternalToken 値の有効期限について

ExternalToken の有効期限は既定で 24 時間となりますが、SharePoint 管理シェルを起動して、下記のコマンドを実行することで変更も可能です。
このタイムアウトの推奨値はデフォルトの 24 時間となりますが、タイムアウトを変更するコマンドはトラブルシューティングや切り分け時に有効です。

$webService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$webService.TokenTimeout = "0:10"
$webService.Update()

対処策

SharePoint がホストされている Windows Server 2008 または Windows Server 2008 R2 サーバーに、下記サポート技術情報から入手可能であるパッチを適用します。
パッチ適用後は再起動が必要となりますためご注意ください。(※ SharePoint のパッチではないため、構成ウィザードの実行は不要です。)

タイトル : SID S-1-18-1 and SID S-1-18-2 cannot be mapped on Windows-based computers in a domain environment
アドレス : https://support.microsoft.com/en-us/kb/2830145

まとめ

Windows Server 2003 のサポート切れに伴い、Windows Server 2012 へのドメイン コントローラーのアップグレードをご検討されている、あるいはアップグレード済みの方も多いと思います。
SharePoint サーバーを Windows Server 2008 または 2008 R2 上にインストールしてご使用の場合、影響を受ける可能性がありますため、是非とも上記パッチの適用をご検討ください。

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