Azure Logic Apps でサービスプリンシパル認証を使ってREST APIを実行する

# 1.はじめに
Azure Logic Apps で REST APIを使用する際の認証方法として、サービスプリンシパル認証についての情報が少なかったため、本記事で紹介致します。

Logic Appsで、Blob StorageやADLS Gen2に対して、コネクターは用意されているものの、痒いところに手が届かないことがあったため、直接REST APIを実行してしまおうとしていたところで、本記事の情報を調査していたので、自分の備忘のために記録しておきます。

# 2. 前提条件
- 予めサービスプリンシパルを用意しておくこと。(参考：[Microsoft Entra ID でクライアント アプリケーションを登録する](https://learn.microsoft.com/ja-jp/azure/healthcare-apis/register-application))
        以下の情報をメモしておきます。
        ・テナント(ディレクトリ)ID
        ・クライアント(アプリケーション)ID
        ・シークレット
- 作成したサービスプリンシパルに対して、Azure Storageの適切なロールを付与します。(参考：[BLOB データにアクセスするための Azure ロールを割り当てる](https://learn.microsoft.com/ja-jp/azure/storage/blobs/assign-azure-role-data-access?tabs=portal))
    *「ストレージ BLOB データ共同作成者」など、実行した操作に応じたロールを付与します。

# 3. Logic Appsの構成
## 3-1. REST API実行までの全体フロー
以下のようなフローで構成しております。
今回は、[Blobへのメタデータ設定のREST API](https://learn.microsoft.com/ja-jp/rest/api/storageservices/set-blob-metadata?tabs=microsoft-entra-id)を実行しております。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2598287/8a0b3af7-918c-b22f-0437-69261bdbb2a0.png)

## 3-2. サービスプリンシパル認証でREST APIを実行するための認証トークンを取得する。

- URI : https://login.microsoftonline.com/<テナントID>/oauth2/token
- Method : POST
- Headers
        - Content-Type : application/x-www-form-urlencoded
- Body
        - grant_type=client_credentials&resource=https://storage.azure.com/
        * 今回Storageへの実行のため「https://storage.azure.com/」を指定しております。
- Authentication
        - Authentication Type : Basic
        - Username : クライアントID
        - Password : シークレット
:::note info
試行錯誤する過程で、Header：Content-Type : application/json での実行を試しましたが、認証に必要なHeaderを正しく読み込むことができなかったので、application/x-www-form-urlencodedにしております。application/json での実行方法がわかる人がおりましたらアドバイスください:baby:
:::


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2598287/2b36e7f4-f787-04c7-b84a-d0ca02580e73.png)

## 3-3 REST APIの実行結果をJSONにパースする。
前述の認証トークンの取得のAPIをPostmanやLogicApps上などで一度実行したレスポンスの結果を、下記イメージの「Use sample payload to generate schema」から読み込ませることで、Schemaを認識させることができます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2598287/e8b5c033-cdf0-acd1-4800-09745e51e90f.png)

## 3-4 REST APIを実行する。
今回実行している、[Blobへのメタデータ設定のREST API](https://learn.microsoft.com/ja-jp/rest/api/storageservices/set-blob-metadata?tabs=microsoft-entra-id)のドキュメントに応じて各種項目を入力します。(本記事の観点から逸れるため、個別のREST APIの説明は割愛します。)

本記事でのポイントとして、サービスプリンシパル認証で取得したアクセストークンを使用する必要があります。

-Headers
    Authorization : Bearer <前述で取得したアクセストークン> 

:::note warn
 * Bearerとトークンの間に、半角スペースを忘れないようにしてください。 
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2598287/a336ebdf-81b6-9d3f-5b2d-a1e8240ae1b1.png)

以上の方法で、サービスプリンシパルを使用したLogicAppsからのREST API実行が可能となります。

# Tips
本記事の内容とは直接関係がないが、本件の動作確認にあたってのその他Tipsについて記載致します。

- LogicApps utcNow()関数での書式設定
Blob APIの必須パラメータ(Date または x-ms-date)に、入力が必要な日付フォーマットが「Mon, 02 Sep 2024 07:25:05 GMT」のようなGMTフォーマットなのですが、 utcNow('R')とすることで実現可能。
その他のパラメーターについては、以下のリンクを参考にしてみてください。

    参考：[標準の日時書式指定文字列](https://learn.microsoft.com/ja-jp/dotnet/standard/base-types/standard-date-and-time-format-strings)

- Blob APIでのメタデータのフォーマットについて
[こちらのページ](https://learn.microsoft.com/ja-jp/rest/api/storageservices/setting-and-retrieving-properties-and-metadata-for-blob-resources)では、以下のように記載されているのですが、個人的にわかりずらかったので、メモしておきます。
    ```
    x-ms-meta-name:string-value  
    ```
リクエストのHeadersでこのようにすると...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2598287/539806b1-7c49-797e-7f6b-8b9a0be2d4ac.png)

このように設定されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2598287/2f5b535c-c409-3744-be32-6803bdba45c4.png)

# 参考
こちらの情報を参考にしました。検索しても、すぐに日本語のページがHitしなかったため、本記事が参考になれば幸いです。
- [invoking HTTP oauth 2.0 from an Azure logic app](https://stackoverflow.com/questions/74404772/invoking-http-oauth-2-0-from-an-azure-logic-app)