Active Directory Authentication Library (ADAL) を使いたかったので、最新の Azure Active Directory V2 PowerShell Module をインストールした環境や、依然に ADAL を使っていた環境でいろいろとやっていたら環境によってスクリプトが動いたり、動かなかったりしたのでなんでだろと思って調べた時のお話です。
ブチザッキ兄さんに聞いてみたらいろいろと教えていただけました。
さすが我らのブチザッキ兄さん。
@kosmosebi ブチザッキ兄さん、ADAL v2っていつから使えないとかあったりするんでしょうか?
ADAL v3になると、トークン生成にAcquireToken使えなくなるみたいで、これつかわない方法に移行する必要があるのか気になったもんで。— Masayuki Ozawa (@Masayuki_Ozawa) June 2, 2017
Microsoft.IdentityModel.Clients.ActiveDirectory.dll が使いたくて、「Install-Module -Name AzureAD」してインストールをしていたのですが、本投稿を書いている時点では、この DLL「3.13.40321.2200」というバージョンの ADAL v3 がインストールされるのですね。
以前作ったスクリプトでは以下のような書き方でアクセストークンを取得してたのですが、最新のバージョンの DLL をインストールした環境ではうまく動かず、以前作った環境では動作するというような状態となっていました。
$token = $authContext.AcquireToken($resourceUri, $clientId, $redirectUri,[Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior]::Always)
[Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext] に ‘AcquireToken’ という名前のメソッドが含まれないため、メソッドの呼び出しに失敗しました。
なんでだろと思って調べてみたところ、AcquireToken method is missing from AuthenticationContext class in Powershell #443 と同じ感じなのかと。
ADAL v3 ですと、AuthenticationContext クラスに「AcquireToken」メソッドがなくなって「AcquireTokenAsync」となっているんですね。
本来であれば、、ADAL v3 に対応させた方がよいとは思うのですが、それ以外のところの調査が本筋だったので、ひとまず ADAL v2 を NuGet から持ってきてそちらの DLL を使用したところ「AcquireToken」が使えて動くようになりました。
Active Directory Authentication Library
nuget install Microsoft.IdentityModel.Clients.ActiveDirectory -Version 2.28.4 #ADAL 2.0 # nuget install Microsoft.IdentityModel.Clients.ActiveDirectory #ADAL 3.0
ADAL v2 であれば、以下のような内容のスクリプトが動作させられるかと。
# 現時点ではこっちの内容の情報が多く、ADAL v3 向けの情報が現時点では少ない気がちょっとしました。
$authorityUri = "https://login.windows.net/common/oauth2/authorize" $resourceUri = "https://analysis.windows.net/powerbi/api" $clientID = "<クライアント ID>" $redirectUri = "https://login.live.com/oauth20_desktop.srf" Add-Type -Path "C:\Microsoft.IdentityModel.Clients.ActiveDirectory.2.28.4\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll" $authContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext($authorityUri) $token = $authContext.AcquireToken($resourceUri, $clientId, $redirectUri,[Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior]::Always)
さらにブチザッキ兄さんから以下の助言をいただけました。
あ、Bearerとるところを生で叩くという話でした
— こすもす.えび (@kosmosebi) June 2, 2017
ちょっと調べてみたところ Authenticating to Azure AD non-interactively で公開されているような情報でもトークン取得できるんですね。
ユーザー名 / パスワードを渡してよいのであれば、以下のような形でサクッと取れました。
$tenantid = "" $clientid = "" $user = "" $password = "" $redirectUri = "https://login.live.com/oauth20_desktop.srf" $resourceUri = "https://analysis.windows.net/powerbi/api" $authorityUri = "https://login.windows.net/common/oauth2/authorize" $tokenendpoint = "https://login.windows.net/{0}/oauth2/token" -f $tennantid $Body = @{ "resource"= $resourceUri "client_id" = $clientID "grant_type" = "password" "username" = $user "password" = $password } $params = @{ ContentType = "application/x-www-form-urlencoded" Headers = @{"accept"="application/json"} Body = $Body Method = "Post" URI = $TokenEndpoint } $token = Invoke-RestMethod @params
参考情報 (後で思い出す用)
- Active Directory Authentication Library
- Azure Active Directory V2 PowerShell Module – General Availability Release
- Azure Active Directory V2 PowerShell Module – Public Preview Release
- ADAL .NET v3 reaches GA!
- How to authenticate Azure Rest API with Azure Service Principal by Powershell
- AcquireToken method is missing from AuthenticationContext class in Powershell #443
- PowerShellでAzure ADの情報を収集
- Azure Management REST API用のBearerトークン
- Authenticating to Azure AD non-interactively