【Functions】Graph APIの参照範囲を特定のSharePointサイトのみに制限する

JavaScript,Windows

こんにちは、しきゆらです。
今回は、前回まとめたSharePointへのファイルアップロードに関連して、特定のサイトにのみ制限する方法を知ったのでメモしておきます。

前回のAzure FunctionsからSharePointへファイルをアップロードする方法については以下をご覧ください。

前回は、ひとまずアップロードできることを目的にしていたので、付与していたAPIスコープが広いものでした。
ただ、実際の場面では誤って意図しないところにファイルを作ったり削除してしまったりする可能性があるため、可能であれば操作できる範囲を絞りたい、というニーズはあるかと思います。

そんな中、MSのドキュメントを見ているとアクセス許可を付与、というAPIがあることを見つけました。

ただ、このAPIを実行することができるのはユーザ委任アクセスのみのような記載です。
できないのか、と思って他のページも見ていたらこんな記事もありました。

こちらのページでは、実現したい特定のサイトのみに制限することができるぞ、という旨の記載になっています。
ということで、このページを参考に設定をしていきます。

特定のサイトのみに制限する手順

大まかには以下の流れで設定していきます。

  • アプリへSites.FullControl.Allの権限を付与する
  • アプリに自己証明書をアップロードする
  • API経由でサイトに対してパーミッションを付与する
  • アプリの権限をSites.Selectedに変更する

では、それぞれ設定していきます。

アプリへSites.FullControl.Allの権限を付与する

こちらのページを見ると、「Sites.FullControl.All」のスコープを持ったアプリ経由での操作となる旨の記載があるので、アプリへ付与します。

Entra IDへアクセスし、以前作成したアプリを開きます。
管理 > APIのアクセス許可から「アクセスの追加」を開き、前回付与した権限はすべて外します。
そして「Sites.FullControl.All」を付与します。

アプリに自己証明書をアップロードする

以下のページを見ると、アプリ専用アクセスでも認証する必要があり、セキュリティの理由から証明書の追加が必要、という旨の記載があります。
ということで、自己証明書を作成して登録します。

なお、この手順では証明書を作成してアプリへ登録するコマンドを実行していますが ここではローカルに証明書を作成してアップロードする形で進めます。

証明書の作成は以下のコマンド。
実行したパスにCertTest.cerができるはずです。
なお、指定しているファイル名は適宜わかりやすい名前を付けてあげてください。

PS C:\\Users\\UserName> New-PnPAzureCertificate -OutPfx CertTest.pfx -OutCert CertTest.cer
New-PnPAzureCertificate: Object reference not set to an instance of an object.

手元の環境では、実行時に上記のようなエラーが表示されました。
ただ、動作自体はしているようでファイルは生成されていたので、同じ現象が起きている方はご注意を。

作成したcerファイルをアプリへ登録します。
アプリの管理 > 証明書とシークレットを開き、証明書タブから「証明書のアップロード」をクリック。
作成したcerファイルを指定し、必要があれば説明欄に概要等を記載して追加しましょう。

ここまででパーミッション付与の準備が完了です。
次の項目から、特定のSharePointサイトへのパーミッション付与を実施します。

API経由でサイトに対してパーミッションを付与する

対象のサイトに対してパーミッションを付与します。
対象はSiteIDで指定する必要があるので、前回の記事を参考に確認しておきましょう。

パーミッション付与は以下のAPIです。

POST https://graph.microsoft.com/v1.0/sites/<SiteID>/permissions 
{
    "roles": [
        "write" // 読み込み・書き込み
    ],
    "grantedToIdentities": [
        {
            "application": {
                "id": "xxxxxxxxxxxxxxxxxxxxx", // アプリ登録で登録したアプリのClient ID
                "displayName": "App Name" // アプリの表示名
            }
        }
    ]
}

成功すると以下のようなレスポンスが返ってきます。

{
  "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#sites('contoso.sharepoint.com,5a58bb09-1fba-41c1-8125-69da264370a0,9f2ec1da-0be4-4a74-9254-973f0add78fd')/permissions/$entity",
  "id": "aTowaS50fG1zLnNwLmV4dHxlMDBiNWUzZi0yMzI1LTQ3MWQtOTljZi1iOGM5ZDlmNDU2N2FANmM5NDA3NWEtZGEwYS00YzZhLTg0MTEtYmFkZjY1MmU4YjUz",
  "roles": [
    "write"
  ],
  "grantedToIdentitiesV2": [
    {
      "application": {
        "displayName": "AddInGuidanceRSC",
        "id": "e00b5e3f-2325-471d-99cf-b8c9d9f4567a"
      }
    }
  ],
  "grantedToIdentities": [
    {
      "application": {
        "displayName": "AddInGuidanceRSC",
        "id": "e00b5e3f-2325-471d-99cf-b8c9d9f4567a"
      }
    }
  ]
}

レスポンス内にあるodata.contextの次にあるidがパーミッションIDとなります。
これが個別に付与したパーミッションを識別するためのIDとなります。 無効にしたい場合にもこのIDが必要になるので、忘れずに保管しておきましょう。

なお、付与したパーミッションの一覧は以下のAPIで確認可能です。

GET https://graph.microsoft.com/v1.0/sites/<SiteID>/permissions

また、付与したパーミッションを取り消す場合は、以下のAPIで可能です。

DELETE https://graph.microsoft.com/v1.0/sites/<SiteID>/permissions/{PermissionID}

アプリの権限をSites.Selectedに変更する

パーミッションの付与が完了したら、Sites.FullControl.Allは不要なので削除してしまいます。
アプリの管理>APIのアクセス許可からSites.FullControl.Allを削除し、Sites.Selectedを付与します。
これにて、特定のサイトにのみアクセスできる設定は完了です。

これにて、設定完了です。

動作確認

パーミッションを付与したサイトへGETメソッドでアクセスしてみて成功したレスポンスが返ってくることを確認しましょう。
そして、パーミッションを付与していないサイトへもアクセスしてみてAccess deniedのレスポンスが返ってくることを確認しましょう。

これにて、特定のサイトに制限することができました。

まとめ

今回は、GraphAPIで操作するSharePointを特定のサイトにのみ制限する方法をまとめました。
前回の記事では広範囲に影響を及ぼしかねない形だったので、それを制限する方法が知れたので良かったかなと。

今回は、ここまで。

おわり

Posted by しきゆら