Azure に OAuth 2.0 Device Flow でログインする

この前az loginでログイン出来なくなった時に、azure cli 2.0 のコードを見ていたら、Azureのドキュメントには出てこない(見慣れない)使い方をしてたので確認も兼ねて生REST、OAuth 2.0 Device Flow[1]でAzrueにloginして Beare Tokenを取得するコンソールプログラムazlogin[2]を書いてみた。

curry

使い方

azloginを実行すると、azure cli 2.0 と同じように、デバイスコードと入力用のURLが表示される。この画面のメッセージがazure cli 2.0と一文一句違わず同じなのは、AIPが返して来るメッセージをそのまま表示してるからだ。

ログインに成功すると、アカウントに紐づいたテナントを全部取得して、テナントのアクセストークンを取得し、それを使ってサブスクリプションの情報を取得。結果をJSONで出力する。

$ .\azlogin
To sign in, use a web browser to open the page https://aka.ms/devicelogin and enter the code G9HFZ4NCY to authenticate.
....
[
   {
     "tenantId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionName": "Developer Program Benefit",
     "bearer": "********************************************a"
   },
   {
     "tenantId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionName": "foo",
     "bearer": "********************************************a"
   },
   {
     "tenantId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionId": "xxxxxxxx-xxxx-xxxxxxxxx-xxxxxxxxxxxx",
     "subscriptionName": "kinmugi",
     "bearer": "********************************************a"
   }
]

このJSONから、Bearer token を取得し変数に保存するして置き、APIの呼び出しをしてみよう。

まずは、jp (JMESPath) の式を用意する。短いのでコマンドラインにそのまま書きたいところだが、Windowsだとエスケープ関係が難しすぎる(cmd.exeや、powershellでは)ので、諦めてファイルに書く。

この例だと、subscriptionName が ‘kinmugi’のサブスクリプションのBearer tokenを取り出している。Windowsだと素直にPowerShellで書いたほうが楽な気がする。最近、JMESPath が気に入っているので、あえてjpを使う。

ここでは、本物のcurlを使って、リソースグループの一覧を取得している。PowerShellだとcurlでaliasが切ってあるが使えないので、本物を入れてalias を切った方が良い。

$ cat filter.jp
[?subscriptionName == 'kinmugi'].bearer|[0]

$ $bearer = (.\azlogin | jp -u -e filter.jp)

$ curl -H  "Authorization: Bearer $bearer" "https://management.azure.com/subscriptions/xxxxxxxx-.../resourcegroups?api-version=2017-05-10"

Bearer tokenさえ手に入れれば、こんな感じでサクッと管理APIが呼べる。

最後に

Azureのドキュメントだとごちゃごちゃしてて良くわからないが、認証は基本普通のOAuth 2.0 なのでそれほど難しくない。このあたりで困ったら、OAuth2.0 のドキュメント(Googleのとか 、翻訳もある[3])を読むと良い。Azure固有の問題は、松崎さんのブログ[4]がお勧めだ。

今回は、生RESTだけで構築したが、認証だけならそれほど難しいことはない。本格的にAzureを触ろうと思うとモデルが欲しくなり。触っていくと大量のモデルが出てくるので自前で作るのはとてもメンドクサイ。その場合はAzureSDKを使うと既にモデルが用意去れているので便利だ。

参考

[1]Using OAuth 2.0 to Access Google APIs,OAuth 2.0 for TV and Limited-Input Device Applications,
[2]Azure Login OAuth 2.0 Device Flow Console Program.
[3]OAuth 2.0 Flow: DevicesYouTube Data APIのドキュメントだが、翻訳されている。
[4]Login UI が出せない Client の OAuth フロー (Azure AD)この記事より松崎さんのブログを読んだほうが良いだろう。

下記のコードも参考になる