Azure Blob Storage ユーザー委任SASを使う

Shared Access Signatures (SAS)を使ってセキュアにAzure Storage Blobにアクセスさせることができます。
アカウントSAS、サービスSAS、ユーザー委任SASと3種類ありますが、ストレージアカウントキーで署名しない方法であるユーザー委任SASを試したので手順に残します。

# ユーザー委任SAS作成
## Azure Portalから
* ストレージアカウントの左メニュー[Shared Access Signature]からはユーザー委任SASを作ることはできません。この画面からはストレージアカウントキーで署名するアカウントSASが作成できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/99a99bc3-9797-8086-b8b4-1454e941409b.png)

* ではユーザー委任SASをPortalから設定するには、コンテナーもしくはBLOBを選択して[SASの生成]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/3bee86f2-e0ad-b9f5-9c98-c2eb0d8ba026.png)

* Portalだとここからユーザー委任SASを作成することができます。このときPortalにログインしているAzure ADユーザーの資格情報を使用して作成されます。尚、ユーザー委任SASの有効期限は最大1週間となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/778358c0-e80a-22e7-7e3c-57ea358a3ed2.png)

* 今回はコンテナーのBLOB一覧を表示したいので、アクセス許可の[読み取り]と[リスト]にチェックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/6bc14b40-2349-0672-1c35-73f73e004d62.png)

* [SASトークンおよびURLを生成]を選択し、[BLOB SAS トークン]をコピーしておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/9087c64f-ca76-daad-0794-746115b6821e.png)

## Azure CLIから
* 次にCLIから作成する方法です。Portalと同じようにAzure ADユーザーでトークンを発行してもよいのですが、こっちはユーザーではなくサービスプリンシパルに権限を与える方法がユースケースとしては多いかなと思います。まずはサービスプリンシパルを作成して、トークンを発行する流れとします。

* Azure ADを選択して、[アプリの登録]→[新規登録]の順に選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/3c9d5769-473d-f22d-b848-f10640f96a6e.png)

* アプリケーション名を入力し、他はデフォルト設定のまま作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/63f7c9e7-795a-8b8f-d47a-3957aaf8286f.png)

* 作成されたら[アプリケーションID]と[テナントID]を控えておきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/48052082-d1ea-c9f7-2f20-d945fc1fc1b0.png)

* [証明書とシークレット]→[新しいクライアントシークレット]の順に選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/348f8c19-d43b-af80-5257-155df176548c.png)

* シークレット名と有効期限を入れて追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/1dbdf7b3-77f8-97f9-6a82-5f529dde733f.png)

* 追加されると[値]がこのときだけ表示されるためメモしておきます。

* 次に自PCでコマンドプロンプトを開きます。必要に応じてAzure CLIを最新化しておきます。

```
az upgrade
```

* 事前に作成したサービスプリンシパルの各種情報を入力してログインします。

```
az login --service-principal --username [アプリケーションID] --password [シークレット] --tenant [ディレクトリID]
```

* ユーザー委任SASを生成します。今回はpermissionsにl(list)とr(read)を付与しています。expiryは1週間以内の日時を指定します。

```
az storage container generate-sas --account-name [ストレージアカウント名] --name [コンテナー名] --permissions lr --expiry 2022-05-01T00:00:00Z --auth-mode login --as-user
```

* SASトークンが返ってくるのでメモしておきます。

# RBAC設定
* ユーザー委任SASを発行したユーザー（今回だとAzure ADユーザーまたはサービスプリンシパル）に、ストレージアカウントへのアクセス権限を与える必要があります。
* ストレージアカウント画面から[アクセス制御(IAM)]→[追加]→[ロールの割り当ての追加]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/ed19e508-d952-9fe0-3135-c1c5713e5142.png)

* 権限は要件次第ですが、今回は[ストレージBLOBデータ閲覧者]を付与します。ここでの注意点は、例えばサブスクリプションに対して[共同作成者]権限が付与されており、このストレージアカウントに権限が継承されていたとしても、個別に[ストレージBLOBデータ共同作成者]等の権限をストレージアカウントに付与してあげる必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/451eb38f-e1de-4c59-3159-d88ba7011aa3.png)

# ユーザー委任SASを使ったアクセス
* az loginしていない新規コマンドプロンプトを起動し、コンテナー配下のBLOBリストを表示してみます。

```
az storage blob list --account-name [ストレージアカウント名] -c [コンテナー名] --sas-token "[ユーザー委任SASトークン]"
```

* ログインしていなくてもユーザー委任SASを使ってアクセスできればOKです。

以上