【GraphAPI】Graph PowerShell (2)：認証 (ユーザー委任権限)

# はじめに

Graph PowerShell を利用すると、ユーザー委任権限、アプリケーション許可権限のどちらの方法でも Graph API を実行することができます。

この記事では、Graph PowerShell からユーザー委任権限で Graph API を実行する方法をまとめました。

※ Graph PowerShell のインストール方法については以下の記事にあります。

https://qiita.com/atsmin77/private/264d10bd9d7e9dfeaace

※ ユーザー委任権限、アプリケーション許可権限の違いについては以下の記事にあります。

https://qiita.com/atsmin77/items/31df2f5624840b45dda0

# ユーザー委任権限で実行する方法

## Connect-MGraph コマンド

Graph PowerShell から Graph API を実行するには、最初に **Connect-MgGraph** コマンドによってサインインします。

ユーザー委任権限とアプリケーション許可権限では、Connect-MgGraph コマンドの実行方法が異なります。ユーザー委任権限では、以下のように **"-Scopes"** に Graph API を実行するためのアクセス許可を指定します。

■ 書式

**Connect-MgGraph -Scopes "\<アクセス許可の名前\>"**

::: note
必要なアクセス許可は Graph API ごとに異なります。各 Graph API の公開情報で [アクセス許可] のセクションに必要なアクセス許可が記載されています。
:::

※ 関連記事

https://qiita.com/atsmin77/items/a1d53031b120da5d9697#23-%E8%A3%9C%E8%B6%B3

■ 例

```powershell
Connect-MgGraph -Scopes "User.ReadBasic.All"
```

※ 複数のアクセス許可を指定する場合は、カンマ区切りで指定します。

```powershell
Connect-MgGraph -Scopes "User.ReadBasic.All", "Team.Create"
```

コマンドを実行してサインインすると、アクセス許可の同意のダイアログが表示されます。

::: note warn
アクセス許可によっては [管理者の同意](https://qiita.com/atsmin77/items/b6bd8def4b9ddc5ab49b#43-%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E8%A8%B1%E5%8F%AF%E3%81%AE%E4%BB%98%E4%B8%8E-%E7%AE%A1%E7%90%86%E8%80%85%E3%81%AE%E5%90%8C%E6%84%8F) が必要になります。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/6acd84c2-17c5-4a88-b30b-26883116e612.png)

**[Accept]** をクリックすると "Welcome to Microsoft Graph!" と表示され 、Graph API を実行できるようになります。

```
Welcome to Microsoft Graph!

Connected via delegated access using xxx-xxx-xxx-xxx-xxx
```

(参考：Delegated access)
https://learn.microsoft.com/ja-jp/powershell/microsoftgraph/authentication-commands?view=graph-powershell-1.0#delegated-access

### Entra ID アプリケーションを指定して実行する場合

アプリケーション許可権限の場合と同様に、Entra 管理センターに登録した Entra ID アプリケーションを指定してコマンドを実行することもできます。

::: note
Entra 管理センターに登録した特定のアプリケーションに対して、アクセス許可を追加して Graph PowerShell を実行することができます。
:::

#### 1. アプリケーションの登録

Entra ID アプリケーションの登録方法はアプリケーション許可権限の場合と同様ですが、以下の点が異なります。

※ 手順の詳細は [アプリケーション許可権限の記事](https://qiita.com/atsmin77/private/a31198368c4a570b801a#11-entra-id-%E3%81%B8%E3%81%AE%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AE%E7%99%BB%E9%8C%B2) を参照してください。
(1.1 Entra ID へのアプリケーションの登録)

* リダイレクト URI の設定内容
リダイレクト URI には以下を設定します。
  | 名前 | 内容 |
  |:-:|:-:|
  | リダイレクト URI | パブリック クライアント / http://localhost |
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/11ee0781-e893-4e84-a60a-2ffbe68d8ca1.png)

* クライアントシークレット
クライアントシークレットを追加する必要はありません。

#### 2. アプリケーションへのアクセス許可の追加

アクセス許可の追加方法もアプリケーション許可権限の場合と同様ですが、以下の点が異なります。

※ 手順の詳細は [アプリケーション許可権限の記事](https://qiita.com/atsmin77/items/b4ab7c00ce1bb8544f90#213-%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E8%A8%B1%E5%8F%AF%E3%81%AE%E8%BF%BD%E5%8A%A0%E6%96%B9%E6%B3%95) を参照してください。
(2.1.3 アクセス許可の追加方法)

* アクセス許可の種類
**[委任されたアクセス許可]** を選択して追加します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/926bab2d-661e-493b-afa7-381d5906af02.png)

必要なアクセス許可を追加したら、**[【テナント名】に管理者の同意を与えます]** をクリックして、[状態] に **[【テナント名】に付与されました]** と表示されることを確認します。

以下の例では "User.ReadBasic.All" と "Team.Create" のアクセス許可を追加しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/5eb59856-7c88-4fff-b55d-f63d00e5241f.png)

#### 3. Connect-MGraph コマンドの実行

以下のように **"-ClientId"** と **"-TenantId"** に Entra ID へ登録したアプリケーションのクライアント ID とテナント ID を指定します。

■ 書式

**Connect-MgGraph -ClientId "\<クライアント ID\>" -TenantId "\<テナント ID\>"**

クライアント ID とテナント ID は登録したアプリケーションの [概要] タブに表示されている値を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2680397/1af15a7b-1d1d-40ac-a085-31df3dc56c1d.png)

■ 例

```powershell
Connect-MgGraph -ClientId "33c089b6-8962-4d4a-b69c-d9054765af1e" -TenantId "ac2852a6-88d6-4ddc-9a63-93391e191144"
```

コマンドを実行してサインインすると、アプリケーションに追加したアクセス許可が付与されていることを確認できます。

```powershell
Get-MgContext | select -ExpandProperty Scopes
```

```
...
Team.Create
User.ReadBasic.All
...
```

(参考：Use delegated access with a custom application for Microsoft Graph PowerShell)
https://learn.microsoft.com/ja-jp/powershell/microsoftgraph/authentication-commands?view=graph-powershell-1.0#use-delegated-access-with-a-custom-application-for-microsoft-graph-powershell

## 補足

### Get-MgContext コマンド

Connect-MgGraph の後に Get-MgContext を実行すると、サインインしたユーザーやアクセス許可の情報を確認することができます。

```powershell
Get-MgContext
```

※ 実行結果の例
```
ClientId               : xxx-xxx-xxx-xxx-xxx
TenantId               : yyyy-yyyy-yyyy-yyyy-yyyy
Scopes                 : {openid, profile, User.ReadBasic.All, email…}
AuthType               : Delegated
TokenCredentialType    : InteractiveBrowser
CertificateThumbprint  :
CertificateSubjectName :
SendCertificateChain   : False
Account                : testuser01@atsmin.net
...
```

::: note
アクセス許可の情報をすべて表示するには以下のように実行します。
:::
```powershell
Get-MgContext | select -ExpandProperty scopes
```

※ 実行結果の例
```
openid
profile
User.Read
email
User.ReadBasic.All
Team.Create
```

### Disconnect-MgGraph コマンド

サインインアウトを行うには、Disconnect-MgGraph を実行します。

```powershell
Disconnect-MgGraph 
```

::: note
Connect-MgGraph コマンドを実行すると、[アクセストークン](https://qiita.com/atsmin77/private/a31198368c4a570b801a#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%88%E3%83%BC%E3%82%AF%E3%83%B3%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6) が取得されます。
アクセストークンの有効期限は既定で 1 時間ですが、Graph PowerShell は自動的にアクセストークンを更新してくれます。
そのため、Disconnect-MgGraph を実行するか PowerShell を終了するまでの間は、継続して Graph API を実行することができます。
:::

(参考：Use Disconnect-MgGraph)
https://learn.microsoft.com/en-us/powershell/microsoftgraph/authentication-commands?view=graph-powershell-1.0#use-disconnect-mggraph
> Microsoft Graph PowerShell automatically refreshes the access token for you and sign-in persists across PowerShell sessions because Microsoft Graph PowerShell securely caches the token.

### Graph PowerShell を使ってアプリケーションを登録する方法

Graph PowerShell を使うと、以下のような操作を PowerShell スクリプトで行うことができます。
* Entra ID アプリケーションの登録
* アクセス許可の追加、変更

以下で PowerShell へコピー & ペーストして実行できるスクリプトの例を紹介します。

#### 例1. アプリケーションの登録とアクセス許可の追加

::: note
Entra ID アプリケーションの登録は、**New-MgApplication** コマンドで行います。
ユーザー委任権限のアクセス許可は **New-MgOauth2PermissionGrant** コマンドで追加します。
:::

```powershell
# 登録するアプリケーションの名前に置き換えてください
$AppName = "Graph PowerShell ユーザー委任権限テスト"
# アプリケーションに追加するアクセス許可にカンマ区切りで置き換えてください
$Permissions = "User.Read.All", "Team.Create"

# サインインダイアログが表示されたら、管理者ユーザーでサインインしてください
Connect-MgGraph -Scopes "Application.ReadWrite.All", "DelegatedPermissionGrant.ReadWrite.All"
$TenantId = (Get-MgContext).TenantId 

# リダイレクト URI を設定して、アプリケーションを作成します
$AppRegistration = New-MgApplication -DisplayName $AppName -PublicClient @{ RedirectUris="http://localhost"; }

# サービスプリンシパルを作成します
$ServicePrincipal = New-MgServicePrincipal -AppId $AppRegistration.AppId
# サービスプリンシパルにアクセス許可を追加します
$GraphResourceId = (Get-MgServicePrincipal -Filter "displayName eq 'Microsoft Graph'").Id
# New-MgOauth2PermissionGrant ではアクセス許可の名前をスペース区切りにして指定します
$Scope = $Permissions -join " "
$PermissionGrant = New-MgOauth2PermissionGrant -ClientId $ServicePrincipal.Id -ConsentType "AllPrincipals" -ResourceId $GraphResourceId -Scope $Scope

# 作成したアプリケーションの情報と追加したアクセス許可を表示します
echo @"
ClientId: $($AppRegistration.AppId)
TenantId: $TenantId
Permissions: $($PermissionGrant.Scope)
"@
```

※ 実行結果の例
```
ClientId: c4594580-8e17-4a51-baaf-67fca9041b07
TenantId: ac2852a6-88d6-4ddc-9a63-93391e191144
Permissions: User.Read.All Team.Create
```

表示された ClientId と TenantId を指定して、[Connect-MgGraph コマンドを実行](#3-connect-mgraph-コマンドの実行) してサインインします。

(参考：New-MgApplication)
https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.applications/new-mgapplication?view=graph-powershell-1.0

(参考：Grant and revoke API permissions in Microsoft Entra ID)
https://learn.microsoft.com/en-us/powershell/microsoftgraph/how-to-grant-revoke-api-permissions?view=graph-powershell-1.0&pivots=grant-delegated-permissions

#### 例 2. アクセス許可の変更

::: note
ユーザー委任権限のアクセス許可の変更は **Update-MgOauth2PermissionGrant** コマンドで行います。
:::

::: note warn
アクセス許可は追加ではなく上書きされるので、<ins>既存のアクセス許可も含めて</ins>変更後のアクセス許可をすべて指定します。
:::

```powershell
# 変更後のアクセス許可にカンマ区切りで置き換えてください
$Permissions = "User.Read.All", "Team.Create", "Group.Create"
# アクセス許可を変更するアプリケーションの ClientId に置き換えてください
$ClientId = "c4594580-8e17-4a51-baaf-67fca9041b07"

# サービスプリンシパルの ID を取得します 
$ServicePrincipalId = (Get-MgServicePrincipal -Filter "AppId eq '$ClientId'").Id
# サービスプリンシパルのアクセス許可を更新します
$OAuth2PermissionGrantId = (Get-MgOauth2PermissionGrant -Filter "clientId eq '$ServicePrincipalId' and consentType eq 'AllPrincipals'").Id
# Update-MgOauth2PermissionGrant ではアクセス許可の名前をスペース区切りにして指定します
$Scope = $Permissions -join " "
Update-MgOauth2PermissionGrant -OAuth2PermissionGrantId $OAuth2PermissionGrantId -Scope $Scope

# 変更後のアクセス許可を表示します
$PermissionGrant = Get-MgOauth2PermissionGrant -Filter "clientId eq '$ServicePrincipalId' and consentType eq 'AllPrincipals'"
echo "Permissions: $($PermissionGrant.Scope)"
```

※ 実行結果の例
```
Permissions: User.Read.All Team.Create Group.Create
```

(参考：Update-MgOauth2PermissionGrant)
https://learn.microsoft.com/en-us/powershell/module/microsoft.graph.identity.signins/update-mgoauth2permissiongrant?view=graph-powershell-1.0

# 関連記事

Connect-MgGraph コマンドによる認証とアクセス許可の同意が完了すると、Graph PowerShell から Graph API を実行することができます。

Graph API の実行方法については以下の記事で紹介しています。

https://qiita.com/atsmin77/private/933b9a08791aed639d38

アプリケーション許可権限で認証する方法については以下の記事で紹介しています。

https://qiita.com/atsmin77/private/6bcc9fb88b305e124399