Microsoft Graph APIでAzure ADを管理

皆さんこんにちは。国井です。

前回、Azure ADのログ管理方法を紹介したところ、Microsoft Graphと呼ばれるAPIを使った管理について、いくつかご意見をいただきました。その中のひとつで、皆さんにも共有しておこうと思ったのが、[アプリの登録]を使うときに証明書ではなく、シークレットを使う方法です。

ちょうど、MSさんのサイトでMS Graph経由でAzure ADのログを取得する方法があり(前回も紹介しましたね)、ここで証明書を使う方法が紹介されていました。

ただ、このやり方だと証明書の管理をしなければならないので、もっと手軽に利用したいというニーズがあるわけです。
そこでシークレットを使うのです!

シークレットは単なる文字列なので、知っている人であれば、いつでもどこでもAPIアクセスができるという便利な仕組み。なので、API経由でちょっとした管理を行いたいという人には喜ばれるのではないかと思います。
(ただし、シークレットは他人に知られたらいけませんので、管理は厳重に!)

設定も簡単で、前回紹介した証明書を登録する画面で、証明書の代わりに[新しいクライアントシークレット]を押してシークレットを生成するだけ。

image

生成したシークレットはPowerShellスクリプトの中で指定するだけでOKです。
前述のMSサイトの中に書かれているスクリプトで言うと、以下の部分を変える感じです。
ちなみにxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx部分にクライアントシークレットの文字列が入ります。また、#$cert =で始まる行(22行目)も不要なので削除してください。(下記のスクリプトでは#で最初からコメントアウトしているので、削除しなくても一応動きます)

Add-Type -Path ".\Tools\Microsoft.IdentityModel.Clients.ActiveDirectory\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
#
# Authorization & resource Url
#
$tenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 
$resource = "https://graph.microsoft.com" 
$clientID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$clientsecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
$outfile = "output.csv"
$data = @()
# tenantID は [Azure Active Directory] - [プロパティ] よりディレクトリ ID を取得します。
# clientID は "Azure AD Reporting API にアクセスするための前提条件" の "アプリケーションのクライアント ID を取得する" の手順で取得します。
# thumbprint は公開キーのアップロードを実行後の "キー" のページで "公開鍵" にサムプリントとして表示されている情報です。
#
# Authorization & resource Url
#
$authUrl = "https://login.microsoftonline.com/$tenantId/"
#

# Get certificate
#
#$cert = Get-ChildItem -path cert:\CurrentUser\My | Where-Object {$_.Thumbprint -eq $thumprint}
 
#
# Create AuthenticationContext for acquiring token 
# 
$authContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext $authUrl, $false
#
# Create credential for client application 
#

$clientCred = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential $clientID, $clientsecret
#
# Acquire the authentication result
#
(以下省略)

これでできあがりです。

Microsoft GraphでAzure ADへアクセス

やっと本題です。ここまで紹介した仕組みを使ってAzure ADのログにアクセスできるのであれば、Azure ADのもっと違うデータにアクセスすることもできるのではないか?と思ったかもしれませんが、まさにその通りです。
Microsoft GraphではAzure ADに格納されている様々なデータにアクセスできるだけでなく、Azure ADに対する設定であったり、Microsoft Intuneなどの他のクラウドサービスに対する操作などもできてしまうのです。
今日はサンプルとして、Azure ADユーザーが利用している多要素認証の方法(音声通話、SMS、Authenticatorアプリなど色々ありますよね)を調べてみたいと思います。

必要なデータにアクセスするためのAPIを調べる

Microsoft Graphで提供するAPI一覧とそれぞれのAPIでアクセス可能なデータ一覧はマイクロソフトのAPIリファレンスサイトで紹介していますので、まずはこれで調べましょう。

ちなみに多要素認証で使う認証方法の情報はReports.Read.AllとAuditLog.Read.Allの2つで、APIを呼び出すときは
https://graph.microsoft.com/beta/reports/credentialUserRegistrationDetails
のように書きます(と、APIリファレンスサイトに書いてありました)。

なお、APIでどれを使えばよいかわからない場合はGraphエクスプローラーを使って調べるのもお勧めです。

image

アプリの登録を作成

Reports.Read.AllとAuditLog.Read.Allの2つのAPIを利用できるアプリの登録を作成します。
前回紹介した方法で[アプリの登録]を作成し、APIのアクセス許可を割り当てておきましょう。

image

PowerShellスクリプトの作成

最後にPowerShellスクリプトを作成します。
スクリプトは前述のMSサイトを参考に次のように作ってみました。
環境によって

$tenantId = 以降の部分にAzure ADのテナントID
$clientID = 以降の部分にクライアントID (アプリケーションID)
$clientSecret = 以降の部分にクライアントシークレット

に書き換えてください。
また、APIアクセスのURLは最後から5行目(44行目)の部分で指定していますが、
もし違うデータにアクセスしたければ、
/beta/reports/credentialUserRegistrationDetails の部分を違うURLに書き換えてください。 

# Authorization & resource Url 
$tenantId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 
$resource = "https://graph.microsoft.com" 
$clientID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" 
$clientSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 

##
## Download NuGet.exe
##
$sourceNugetExe = "https://dist.nuget.org/win-x86-commandline/latest/nuget.exe"
$targetNugetExe = ".\nuget.exe"
Remove-Item .\Tools -Force -Recurse -ErrorAction Ignore
Invoke-WebRequest $sourceNugetExe -OutFile $targetNugetExe
Set-Alias nuget $targetNugetExe -Scope Global -Verbose
##
## Download Microsoft.IdentityModel.Clients.ActiveDirectory.dll
##
./nuget install Microsoft.IdentityModel.Clients.ActiveDirectory -O .\Tools
md .\Tools\Microsoft.IdentityModel.Clients.ActiveDirectory
$prtFolder = Get-ChildItem ./Tools | Where-Object {$_.Name -match 'Microsoft.IdentityModel.Clients.ActiveDirectory.'}
move .\Tools\$prtFolder\lib\net45\*.* .\Tools\Microsoft.IdentityModel.Clients.ActiveDirectory
Remove-Item .\Tools\$prtFolder -Force -Recurse
##
## Remove NuGet.exe
##
Remove-Item nuget.exe

##
## MS Graph Access
##
Add-Type -Path ".\Tools\Microsoft.IdentityModel.Clients.ActiveDirectory\Microsoft.IdentityModel.Clients.ActiveDirectory.dll"
 
# Authorization & resource Url
$authUrl = "https://login.microsoftonline.com/$tenantId/"
# Create AuthenticationContext for acquiring token
$authContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext $authUrl, $false
# Create credential for client application
$clientCred = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.ClientCredential $clientID, $clientSecret
# Acquire the authentication result
$authResult = $authContext.AcquireTokenAsync($resource, $clientCred).Result
# Get data from MS Graph
if ($null -ne $authResult.AccessToken) {
     $headerParams = @{'Authorization' = "$($authResult.AccessTokenType) $($authResult.AccessToken)"}
     Invoke-RestMethod -Uri "$resource/beta/reports/credentialUserRegistrationDetails" -Headers $headerParams -ContentType “application/json” | select -ExpandProperty value
}
else {
     Write-Host "ERROR: No Access Token"
}

実行結果がこちら。

ご覧のようにユーザーごとに多要素認証で利用している認証方法がauthMethodsプロパティに表示されていることがわかります。
もうちょっと見やすく表示するならスクリプトの最後から5行目を次のように変えるのもひとつの方法です。

Invoke-RestMethod -Uri “$resource/beta/reports/credentialUserRegistrationDetails” -Headers $headerParams -ContentType “application/json” | select -ExpandProperty value | ft UserDisplayName, authMethods -Autosize

この場合の実行結果はこちら。

image

今回は参照するところに注力しましたが、もちろんPowerShellですからCSV形式にして他のアプリと連携したり、Invoke-RestMethod –Method POST… と書いてAzure ADに対する設定を行ったり、色々なことに応用できると思います。