Azure API Managementの資格情報マネージャーを使ってBlob storageにアクセスする

このエントリは2024/04/30現在の情報に基づいています。将来の機能追加や変更に伴い、記載内容からの乖離が発生する可能性があります。

問い合わせ

以下の2エントリを読んでくれたお初の人からのお問い合わせ。

いま、Blob storageのREST APIの認証周りの手間を軽くするために、API Management(以下APIM)を挟むことを検討している。以前のエントリを読んで、Managed Identityを使う方法はよく理解できたが、資格情報マネージャーも利用可能なのだろうか?資格情報マネージャーを使うとどんないいことがあるのか。

「ユーザー委任かそうでないか、の違いだと思うのだが」という言葉は飲み込みつつ、果たしてどうなのか、ということで試してみた(自分の理解のため、と言い聞かせる)。結論から言うと、利用可能ではあるが、Azureリソースに対して使う場合にはManaged Identityのほうが便利かつ簡単である。

資格情報マネージャーについて

先ほどのエントリにも記載の通り、OAuth 2.0での認可が必要なバックエンドサービスに対して、トークンを取得したり、更新したりしてくれるもの。

API 資格情報と資格情報マネージャーについて / About API credentials and credential manager
https://learn.microsoft.com/azure/api-management/credentials-overview

Authorization code grant flow、Client credential grant flowのいずれかを利用できるが、それぞれで当然挙動が異なる。

種類誰の権限・ロールを使うか想定ユースケース
Authorization code grant flowUser impersonation(言葉の意味はユーザー偽装だが、ユーザー委任がしっくりくる)なので、APIを呼び出すユーザーの権限でアクセスする。Webアプリ(UIでの操作など)
はじめて操作する場合には、権限を付与するか否かの同意が必要
Client credential grant flowクライアントアプリの権限・ロールでアクセスする。Microsoft Entra IDの場合、アプリの登録(App registrations)で登録したアプリのService Principalに付与した権限・ロール。バックエンドアプリ(UIの操作無し)

今回は、Put Blobを使った操作をラップしたAPIの作成を通じて説明することにした。Blob REST APIのPut BlobのReferenceは以下を参照。

Put Blob
https://learn.microsoft.com/rest/api/storageservices/put-blob?tabs=microsoft-entra-id

API作成のために、以下の作業が必要である。

  1. Microsoft Entra ID
    • アプリ登録
    • シークレットの作成
    • APIの許可
  2. Blob storage
    • コンテナーに対する権限付与(RBAC)
  3. APIM
    • 資格情報マネージャーへの登録
    • APIの作成

作業は以下のチュートリアルとほぼ同じ。Graph API固有の部分以外はそのまま使える内容である。以下ではStorage APIに特化した部分を加えつつ、備忘録として記載しておく。

資格情報マネージャーの構成 – Microsoft Graph API / Configure credential manager – Microsoft Graph API
https://learn.microsoft.com/azure/api-management/credentials-how-to-azure-ad

1. Microsoft Entra IDでの作業

アプリの登録

Authorization code grant flow、Client credential grant flowのいずれを使う場合でも、アプリを登録する必要がある。今回はMicrosoft Entra IDに登録するため、Entra ID>アプリの登録(App registrations)を選択し、下表に従って設定しておく。

項目設定内容
名前
(Name)
任意
アカウントの種類
(Supported account types)
Single tenant
リダイレクトURI
(Redirect URI)
https://authorization-manager.consent.azure-apim.net/redirect/apim/{APIMサービス名}

作成すると、Client IDが生成され、表示されるので、メモしておく(この値は後からでも確認できる)。

シークレットの作成

アプリのPrincipal作成完了後、シークレットを作成する。Certificates & secrets > Client secrets を選択し、New client secretをクリックすると、Add a client secretという画面がAzure Portalの右側に現れるので、Descriptionと期限を設定して【Add】(追加)をクリックする。するとシークレットが現れるが、このシークレットは再表示できないので、必ずメモを取っておくこと。

APIの許可(API Permissions)

どのAPIのどのスコープを使えるようにするか、を設定する。まず【Add permission】をクリックし、Azure Portal右側に現れる画面から、【Azure storage】を選択する。

API許可のリクエスト画面が現れるので、user_impersonationにチェックを入れて、【Add permissions】を選択。このスコープは管理者による同意が不要なので、管理者に作業依頼する必要はない。

これで、Microsoft Entra IDでの作業はおしまい。

2. Blob storageでの作業

Storage accountを作成し、Blob containerを作成しておく。名前は何でもよい。Blob container作成後、Blob containerにRBACを構成する。付与するロールはStorage Blob Data Contributorロールだが、Authorization code grant flowでユーザー委任する場合と、Client credential grant flowで構成する場合では、付与対象のプリンシパルが異なる点に注意。

種類付与するロール付与するプリンシパル
Authorization Code grant flowStorage Blob Data Contributorロール登録したアプリ
操作を委任するユーザーアカウント
Client credential grant flowStorage Blob Data Contributorロール登録したアプリ

BLOB データにアクセスするための Azure ロールを割り当てる / Assign an Azure role for access to blob data
https://learn.microsoft.com/azure/storage/blobs/assign-azure-role-data-access?tabs=portal

これで、Blob storageに対する作業はおしまい。

3. APIMでの作業

資格情報マネージャを使って資格情報プロバイダと接続を作成する。APIs > Credential manager (資格情報マネージャ)を選択し、Create(作成)をクリックして資格情報プロバイダを作成する。

必須項目には、アスタリスクが付いているのですぐわかるはず。

入力にあたっての注意点は以下。

設定項目ポイント
Tenant IDMicrosoft 365を管理しているMicrosoft Entra IDと、Azureサブスクリプションを管理しているMicrosoft Entra IDが異なる場合は、明示的にIDを指定するのが吉(無用なエラーに悩まされなくて済む)
Authorization URLhttps://login.microsoftonline.comでよい
Resource URL今回はBlob storageなので、Blob storageのエンドポイントを指定する。Blob containerを含むFQDNは不要。
https://<Storage account名>.blob.core.windows.net/
Scopes登録済みアプリで構成していれば、自動的に選択してくれるので、記載不要

このあと、接続の確認をして、問題なければ、資格情報マネージャでの作業はおしまい。

APIの作成

資格情報マネージャで取得したアクセストークンをHTTP Headerに設定する必要がある。以前のエントリでも記載したが、Provider IDとAuthorization IDはそれぞれ資格情報プロバイダ名、接続名である点に注意。

<policies>
    <inbound>
        <base />
        <get-authorization-context provider-id="{プロバイダ名}" authorization-id="{接続名}" context-variable-name="auth-context" identity-type="managed" ignore-error="false" />
        <set-header name="Authorization" exists-action="override">
            <value>@("Bearer " + ((Authorization)context.Variables.GetValueOrDefault("auth-context"))?.AccessToken)</value>
        </set-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

Put blobの操作に必要なHTTP Headerもつけておく必要がある。これらはAuthorization code grant flowとClient credential grant flowの操作に共通するので、All Operationsスコープで構成している。

<policies>
    <inbound>
        <base />
        <set-header name="x-ms-version" exists-action="override">
            <value>2024-05-04</value>
        </set-header>
        <set-header name="x-ms-blob-type" exists-action="override">
            <value>BlockBlob</value>
        </set-header>
    </inbound>
    <backend>
        <base />
    </backend>
    <outbound>
        <base />
    </outbound>
    <on-error>
        <base />
    </on-error>
</policies>

これでAPI Managementでの作業はおしまい。

Let’s try!

Authorization code grant flowの場合、ユーザー委任による操作なので、最初にAPIにアクセスする際に同意(Consent)を求められる(管理者がすでに同意していればその限りではない)。アクセスに使ったBearerトークンを見ると、ユーザー情報が含まれているのに対し、Client credential grant flowの場合は操作を委任していないので、当然ながらユーザー情報は含まれず、登録したアプリのClient IDがJWTのappIdに入っている(さすがにスクリーンショットはご勘弁を)。

どちらのフローを使うべきか?

Client credential flowはバックエンドで利用する(ユーザーによる操作が入らない)ことを想定したものであるため、操作を委譲したユーザーを追跡する必要がない場合には、シンプルに構成できる。

対してAuthorization code grant flowは、「ユーザーによる操作の委任」という形でAPIを実行できる。そのため、Webアプリケーションでユーザーの操作が発生するようなケースと相性がよい。さらに、委任元(操作を委任したユーザー)をバックエンドAPIで取得できるなら、操作委任証跡として利用する、つまり誰がその操作を実施したのか、を追跡するための証跡としても利用できる(実際に操作を立証するには、複数の証跡を合わせて立証することになるだろうが)。

Managed Identityを使って同じことはできないのか?

可能だが、一部制限がある。まず、Managed IdentityはMicrosoft Entra IDで登録されたアプリのように利用可能なプリンシパルである。

Azure リソースのマネージド ID とは / What are managed identities for Azure resources?
https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/overview

このManaged Identityは、Azureをスコープとしており、Microsoft 365などはスコープ外。そのため、バックエンドサービスとしてAzureリソースを活用するようなAPIを作成する場合、APIMのManaged Identityを使ったアクセスのほうがシンプルで、わざわざ

  • Microsoft Entra IDでアプリを登録
  • 資格情報マネージャで認証を構成し、接続を作成

という作業がなくなるのはその通り。ただし、スコープ外のリソース(Microsoft 365や3rdパーティーAPI)に対しては使えないため、資格情報マネージャを使うしかない。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください