2013 形式ワークフローでリストアイテムの権限変更を行う方法について

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

今回の投稿では、SharePoint Online (または SharePoint Server 2013 On-Premises) において 2013 形式ワークフローで権限変更を行う方法についてご紹介します。

 2019.2.18 追記 
本ブログ記事には、SharePoint Online における現在の見解とは異なる内容が多く記載されていたため、大幅に編集しております。

導入 : 詳細に設定されたアクセス許可(FGP) を実現する方法

事前注意 : SharePoint でアイテムごとに個別にアクセス権を付与するとパフォーマンス劣化の要因となります。はじめに要件定義や設計フェーズで、この運用の方針を回避いただくことをお勧めします。どうしても、アイテムごとにアクセス権を付与する方法を実現するためにはカスタマイズが必要となりますが、リストやライブラリ スコープの上限については十分な注意を払ってください。

SharePoint Online ・・・ 5,000
SharePoint オンプレミス ・・・ 50,000 (ただし推奨は 5,000)

タイトル : SharePoint Online の制限
アドレス : /ja-jp/office365/servicedescriptions/sharepoint-online-service-description/sharepoint-online-limits

方法論 : SharePoint On-Premises 製品で本機能を実現する場合は、迷わず Visual Studio を使用してファーム ソリューションでアイテム イベント レシーバーを開発し展開することが適切です。つまり、ItemAdded や ItemUpdated イベントにおいて SPListItem.BreakRoleInheritance(false) メソッドを呼び出し、SPListItem.RoleAssignments.Add() メソッドで必要なロール割り当てを指定する方法です。

ただし、SharePoint Online では、ファーム ソリューションでの開発はできません。そこで、以下の代替案に行き着くことになりますが、どの選択肢も制約があります。

代替案 1) サンドボックス ソリューションでイベント レシーバーを開発する。

  コード ベースのサンドボックス ソリューションのサポートはすでに終了しています。

代替案 2) Azure などのクラウド環境を調達し、リモート イベント レシーバーをホストさせる。

  リモート イベント レシーバーのためだけに、オンラインのクラウド環境を調達することは、コストの面からもビジネス的に厳しいと想定しています。
また、機能的には実現可能ではあるものの、アプリの並列実行による集中アクセスは HTTP 調整の対象となりやすく、処理が滞る危険性が懸念されます。

代替案 3) 2010 形式ワークフロー アクションを使用する

  代理ステップの上でリストアイテムの権限を置換するなどのアクションを使用することが実装工数上最も現実的に見えます。権限の割り当てが多いときに、大量のアイテム作成・更新を行い、これらのアクションを実行するとパフォーマンス上問題を引き起こし、かなりの高確率でワークフローがエラー終了する現象が報告されています。

タイトル : ワークフロー アクション クイック リファレンス (SharePoint 2010 ワークフロー プラットフォーム)
アドレス : https://msdn.microsoft.com/ja-jp/library/office/jj822977%28v=office.15%29.aspx

代替案 4) 2013 形式ワークフローを使用して HTTP Web サービスを呼び出して権限を変更する。

  SharePoint 2013 形式ワークフローにも、大きなダウンタイムを伴うような調整が導入されていることは認識しておく必要がございます。

タイトル : sharepoint 2013 のワークフロー調整とパフォーマンス (sharepoint online と Project online)
アドレス :https://support.office.com/ja-jp/article/sharepoint-2013-のワークフロー調整とパフォーマンス-sharepoint-online-と-Project-online-a4971057-ea08-461a-a2e8-644674a9f008

上記のような懸念はありますが、技術的な方法論として本記事を残す方針としております。2013 形式ワークフローには、権限変更に関するアクションは標準提供されていないため、手順は複雑になります。ここに記載された画面付きの手順をお役立ていただけますと幸いです。

補足
現在のところ、マイクロソフト見解としては、SharePoint 2010 形式と 2013 形式ワークフローは、どちらもレガシー テクノロジーとして認識されております。現時点では 2010 形式ワークフロー (下位互換ワークフロー) および 2013 形式ワークフローが、今後使用できなくなるといった情報や方針は出されていません。

この投稿で 2013 形式ワークフローを選択する理由は、2013 形式ワークフローは REST 呼び出しで BreakRoleInheritance(false) を使用できるという限定的な内容が焦点であり、それ以外に意図はありません。 2010 形式ワークフローの弱点は、BreakRoleInheritance(true) を使用している点です。これは親であるリストなどに権限が 100 個登録されていた場合、あとで全て削除するにせよ一旦 100 個コピーする方法です。高性能なサーバー上で実現された SharePoint Online であっても、これを頻発すると大量のレコードの追加と削除が繰り返され、サイト内のパフォーマンス劣化が生じます。

2010 形式ワークフローが、BreakRoleInheritance(true) を使用している理由は、リスト アイテムの権限を追加する、リスト アイテムの権限を削除する アクションなど、権限を差分で編集する機能が存在し、それらのアクションを含めた権限系の操作を行う外部メソッドがコードを共有している点にあります。

なお、SharePoint On-Premises で 2013 形式ワークフローを使用する場合、障害復旧などのシナリオが複雑になる点については、あらかじめご理解ください。

タイトル : Understanding SharePoint 2013 Workflow Backup
アドレス : https://technet.microsoft.com/ja-jp/library/jj937239(v=office.15).aspx

タイトル :  SharePoint 2013 形式ワークフローの障害復旧について
アドレス : https://blogs.technet.microsoft.com/sharepoint_support/2016/04/12/sharepoint-2013-%e5%bd%a2%e5%bc%8f%e3%83%af%e3%83%bc%e3%82%af%e3%83%95%e3%83%ad%e3%83%bc%e3%81%ae%e9%9a%9c%e5%ae%b3%e5%be%a9%e6%97%a7%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6/

実践 : 2013 形式ワークフローで権限変更を行う方法について

今回ご案内する手順は、アイテムのユーザー列 (例. user) に指定されたユーザーにフルコントロール権限を与える方法です。

1. 事前準備

1) " ワークフローでアプリの権限を使える" 機能の有効化

以下の手順にてサイトの "ワークフローでアプリの権限を使える" 機能を有効にします。

1-1) ブラウザにてサイトにアクセスします。

1-2) [*] - [サイトの操作] - [サイトの設定] をクリックします。

1-3) [サイト機能の管理] をクリックし、"ワークフローでアプリの権限を使える" 機能を有効にします。

 

2. クライアント セクションの取得

2-1) ブラウザにてサイトにアクセスします。
2-2) [*] - [サイトの設定] - [サイト アプリの権限] をクリックします。

 

 

 

2-3) ワークフロー アプリのアプリ ID 中のID の最後の "|" と "@" 記号の間の部分をコピーします。

 

例 : アプリ ID = i:0i.t|ms.sp.ext|df119aab-5d1a-4067-b490-e95e6516a448@4837bbfb-2dd1-4579-8f94-8438f138f12f

クライアント セクション : df119aab-5d1a-4067-b490-e95e6516a448

3) アプリの権限設定

以下の手順にて、対象となるサイトの appinv.aspx にてワークフロー アプリの権限として以下の XML を追加します。

3-1) ブラウザにて以下にアクセスします。 例) https://<サイト コレクションURL>/_layouts/15/appinv.aspx 3-2) 2 で取得したクライアント セクション を入力して [参照] をクリックしてデータを照会した上で、アプリの権限要求 XML に以下を追加いたします。

 <AppPermissionRequests>
  <AppPermissionRequest Scope="https://sharepoint/content/sitecollection" Right="FullControl" />
</AppPermissionRequests>


3-3) [作成] をクリックし、ワークフロー アプリを信頼することを求められます。[信頼する] をクリックします。

 参考情報

  詳細につきましては、以下の弊社公開情報をご参考いただきますと幸いです。

  タイトル : SharePoint 2013 ワークフロー プラットフォームを使用した引き上げられた権限でのワークフローの作成
アドレス : https://msdn.microsoft.com/ja-jp/library/office/jj822159(v=office.15).aspx

 

2. SharePoint Designer 2013 で 2013 モードのワークフローを作成する

  1) SharePoint の管理者ユーザーで SPD 2013 を起動します。
  2) メニューバーより、[ファイル] - [サイト] - [サイトを開く] をクリックします。
  3) ダイアログが表示されますので、サイト名 (例 <https://tenant.sharepoint.com/sites/site) を入力して [開く] をクリックします。
4) ナビゲーションより、[ワークフロー] をクリックし、リボン上の "リスト ワークフロー" - <<該当リスト>> をクリックします。
5) "プラットフォームの種類 : SharePoint 2013 ワークフロー" の設定し、任意の名前でワークフローを作成します。

 

 6) ステージ 1 の "(入力するか、リボンの [挿入] グループを指定してください)" の下をクリックし、リボン上の [アプリ ステップ] を挿入します。  
 

ここから先は、ご要望の動作に合わせて、アプリステップの中に [辞書を作成] と [HTTP Web サービスを呼び出す] をクリックして配置していきます。画像でアクションの配置されている位置を確認ください。

 

 

8) HTTP Web サービスを呼び出す際に使用する HTTP Request Header を辞書型で作成します。

8-1) "アクション" - "辞書を作成" をクリックします。

8-2) "この" をクリックし、[追加] をクリックし、以下の登録を実施します。

名前 : Accept   種類 : 文字列  値 : application/json;odata=verbose

名前 : Content-Type   種類 : 文字列  値 : application/json;odata=verbose

 

8-3) "変数:辞書" - "新しい変数の作成" をクリックし、辞書型の変数 (例: RequestHeader) を作成します。

9) HTTP Web サービスを呼び出して権限の継承を中止し、固有の権限を作成します。

9-1) "http Web サービスを呼び出す" アクションを挿入します。

9-2) 挿入したアクションを選択し、右クリック - [プロパティ] を選択し以下の設定を実施します。

 

  9-3) "RequestType" に、"HTTP POST" を指定します。
9-4) "RequestHeaders" に、8-2) で作成した変数 (例: RequestHeader) を指定します。
9-5) "ResponseContent" をクリックし、新しい変数をクリックして ResponseContent という辞書型の変数を作成します。

 

 

9-6) "Address" にフォーカスした際に現れる "…" をクリックし、文字列ビルダーを呼び出してリクエスト先の URL を構成します。

9-7) 下記の様に REST で BreakRoleInheritance メソッドを呼び出します。

例)
https:///_api/web/lists/GetByTitle(%27[%ワークフローコンテキスト:リスト名%]%27)/items([%現在のアイテム:ID%])/breakroleinheritance(false)

 

補足

Web サービスのパラメーター部分 ([% %] で囲まれた箇所) は、上記図のように [参照の追加または変更] をクリックして、適宜パラメーターを埋め込みます。

 

10) HTTP Web サービスを呼び出して、アイテムのユーザー列に指定されたユーザー列に権限を付加します。

10-1) アドレス以外の指定は上記と全く同じです。

10-1-1) "RequestType" に、"HTTP POST" を指定します。

10-1-2) "RequestHeaders" に、8-2) で作成した変数 (例: RequestHeader) を指定します。

10-1-3) "ResponseContent" をクリックし、新しい変数をクリックして ResponseContent という辞書型の変数を作成します。

10-2) アドレス部分は下記の様に AddRoleAssignment メソッドを呼び出します。

例)

https:///_api/web/lists/GetByTitle(%27[%ワークフローコンテキスト:リスト名%]%27)/items([%現在のアイテム:ID%])/roleassignments/addroleassignment(principalid=[%現在のアイテム:User%],roleDefId=1073741829)

 

 

補足

roleDefId パラメーターとして指定している 1073741829 は、フルコントロール権限です。

ブラウザ上で、以下の URL にアクセスの上、ご要望のroleDefid (d:Id m:type) をご確認ください。

https:///_api/web/roledefinitions

 

11) 最後に微調整を行います。

・エラー発生時の調査用に ResponseContent を履歴リストに出力します。

・リストビュー上でワークフローが完了したことを把握しやすくするため、完了ステージに一度遷移させ、ワークフローを終了させます。

  12) リボン メニューより[ワークフローの設定] をクリックして、開始オプションを設定します。

13) ワークフローの発行を実施します。

補足

ワークフローで SharePoint の REST API を実施できるようになり、ワークフローで実現できることが SharePoint 2010 形式のワークフローより多くのことが実現可能となりました。
なお、権限を昇格して実施するような処理に関してはアプリ ステップを利用する必要がございます。
以下のサイトにも上記手順に関する記載がございますのでご参考にしていただければ幸いです。

タイトル: ワークフロー アクション クイック リファレンス (SharePoint 2013 ワークフロー プラットフォーム)
アドレス: https://msdn.microsoft.com/ja-jp/library/office/jj164026(v=office.15).aspx

タイトル: SharePoint 2013 ワークフロー プラットフォームを使用した引き上げられた権限でのワークフローの作成
アドレス: https://msdn.microsoft.com/ja-jp/library/office/jj822159(v=office.15).aspx

タイトル: SharePoint 2013 REST サービスの概要
アドレス: https://msdn.microsoft.com/ja-jp/library/office/fp142380(v=office.15).aspx

タイトル: ワークフローで HTTP Web サービスを利用する
アドレス: https://blogs.technet.com/b/sharepoint_support/archive/2014/08/15/http-web.aspx

タイトル: SharePoint Designer 2013 の辞書アクションを理解する
アドレス: https://msdn.microsoft.com/JA-JP/library/office/jj554504(v=office.15).aspx