MSAL.PS を使って Azure AD アクセストークンを取得する


# はじめに

非対話で Azure AD からアクセストークンを取得する場合、以下のようなかんじで REST API 経由で取得していることでしょう。

```powershell:REST&#x20;API&#x20;経由でアクセストークンを取得
$clientId = '{your application id}'
$clientSecret = '{client secret}'
$tenantId = '{your tenant id}'
$loginUrl = "https://login.microsoftonline.com/$tenantId/oauth2/token"
$resource = 'https://api.loganalytics.io'
$oauthReqBody = @{
    'grant_type' = 'client_credentials'
    'resource' = $resource
    'client_id' = $clientId
    'client_secret' = $clientSecret
}

$oauth = Invoke-RestMethod -Method Post -Uri $loginUrl -Body $oauthReqBody
```

ここでは「クライアント シークレット」を用いていますが、これを「証明書」に変更したい場合、REST API 経由でアクセストークンを取得するスクリプトはとてもムズカシイです。[^1]


# MSAL.PS

そこで、利用するのが [MSAL.NET](https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/wiki) 機能を PowerShell 対応のコマンドレットにラップした **「MSAL.PS PowerShell モジュール」** です。
これ自体、Microsoft のサポート外なものですが、これを利用すればとてもカンタンに書くことができます。

https://github.com/AzureAD/MSAL.PS

ちなみに、MSAL.NET とは...

> Azure AD からトークンを取得して、保護された Web API (Microsoft API または Azure Active Directory に登録されているアプリケーション) にアクセスできるようにする認証ライブラリです。


# さっそく使ってみよう

まず、PowerShell ギャラリーからこのモジュールをインストールしましょう。

```powershell
Install-Module MSAL.PS
```

そして、このモジュールをインポートしましょう。

```powershell
Import-Module MSAL.PS
```

最後に、「Get-MsalToken」コマンドを実行することにより、Azure AD からアクセストークンを取得することができます。戻り値は [Microsoft.Identity.Client.AuthenticationResult](https://docs.microsoft.com/en-us/dotnet/api/microsoft.identity.client.authenticationresult?WT.mc_id=AZ-MVP-5003113&view=azure-dotnet) のオブジェクトです。

では、以下より、Azure Monitor Log Analytics API の使用を例にスクリプトを書いてみます。

https://docs.microsoft.com/ja-jp/azure/azure-monitor/logs/api/overview?WT.mc_id=AZ-MVP-5003113

Azure AD へのアプリの登録についての設定は、以下のドキュメントをご参考にしてください。

https://docs.microsoft.com/ja-jp/azure/azure-monitor/logs/api/authentication-authorization?WT.mc_id=AZ-MVP-5003113


## 証明書の場合

証明書を用いてアクセストークンを取得するには、以下のようなかんじで書きます。
とてもシンプルにスクリプトを書くことができます。

```powershell:MSAL.PS&#x20;を使ってアクセストークンを取得&#x20;(証明書編)
$clientId = '{your application id}'
$certName = 'example'
$clientCert = (Get-ChildItem Cert:\CurrentUser\My | ? {$_.Subject -eq "CN=$certName"})
$tenantId = '{your tenant id}'
$scope = 'https://api.loganalytics.io/.default'

$oauth = Get-MsalToken -ClientId $clientId -TenantId $tenantId -ClientCertificate $clientCert -Scopes $scope
```

## クライアント シークレットの場合

ちなみに、クライアント シークレットを用いてアクセストークンを取得するには、以下のようなかんじで書きます。
こちらもシンプルなスクリプトになりましたね。

```powershell:MSAL.PS&#x20;を使ってアクセストークンを取得&#x20;(クライアント&#x20;シークレット編)
$clientId = '{your application id}'
$clientSecret = '{client secret}'
$password = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force
$tenantId = '{your tenant id}'
$scope = 'https://api.loganalytics.io/.default'

$oauth = Get-MsalToken -ClientId $clientId -TenantId $tenantId -ClientSecret $password -Scopes $scope
```

## ちょっとコマッタこと

余談ですが、ちょっと困ったのは ```-Scopes``` パラメーターの指定のしかた。どのような値を指定すれば良いか悩みましたが、先人の知恵をお借りしたところ、 ```https://api.loganalytics.io/.default``` と指定するそうです。[^2]



[^1]:[こちらのブログ記事](https://blog.haniyama.com/2021/04/24/get-aad-token-using-powershell/)を拝見して :scream: としました... :sweat_smile:
[^2]:[先人の知恵](https://stackoverflow.com/questions/66579576/using-the-log-analytics-rest-api-with-msal-instead-of-adal)です。多謝 :hearts: