目次
検証環境
- Azure Functions v3
- Azure Storage Blobs v12.8.0
概要
Shared Access Signatures (SAS) は、リソースへのアクセス権に制限を付けてトークンを生成し、Shared Access Signatures URI を使ってリソースへのアクセスを許可する。
SASの種類は3種類。
制御できる項目。
- アクセスできるリソース
- 書き込み、読み取りなどのアクセス許可
- トークンの有効期限
- IP制限
生成するには、ポータルや Microsoft Azure Storage Explorer を使う方法、プログラムで生成するなどがある。
ここではサービス SAS をプログラムで発行するサンプルとなる。 また、保存されているアクセス ポリシーにサービス SAS が関連付けられないため、強制的に失効させることができないので取り扱いは注意が必要。 有効期限を 1 時間以下に設定することが推奨されている。
実装
コンテナの SAS トークン
private static string _connectionString = "connectionString"; private static string _container = "container"; [FunctionName("GetAccessToken")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { var (url, token) = await GetContainerSasToken(); log.LogInformation(url + token); return new OkObjectResult(token); } public static async Task<(string, string)> GetContainerSasToken() { var account = CloudStorageAccount.Parse(_connectionString); var client = account.CreateCloudBlobClient(); var container = client.GetContainerReference(_container); await container.CreateIfNotExistsAsync(); var policy = new SharedAccessBlobPolicy() { SharedAccessStartTime = DateTime.UtcNow.AddMinutes(0), SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(3), Permissions = SharedAccessBlobPermissions.Read | SharedAccessBlobPermissions.List, }; var token = container.GetSharedAccessSignature(policy, null, null, null); // IP制限 //var ipRange = new IPAddressOrRange("168.1.5.65"); //var ipRange = new IPAddressOrRange("168.1.5.60", "168.1.5.70"); //var token = container.GetSharedAccessSignature(policy, null, null, ipRange); return (container.Uri.AbsoluteUri, token); }
ログに出力される URI は :
が %3A
にエンコードされているので :
に戻すとそのままの URI でブラウザでアクセスできる。
Blob の SAS トークン
private static string _connectionString = "connectionString"; private static string _container = "container"; private static string _blobName = "blobName"; [FunctionName("GetAccessToken")] public static async Task<IActionResult> Run( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log) { var (url, token) = await GetBlobSasToken(); log.LogInformation(url + token); return new OkObjectResult(token); } public static async Task<(string, string)> GetBlobSasToken() { var account = CloudStorageAccount.Parse(_connectionString); var client = account.CreateCloudBlobClient(); var container = client.GetContainerReference(_container); await container.CreateIfNotExistsAsync(); var blob = container.GetBlockBlobReference(_blobName); var exists = await blob.ExistsAsync(); if (!exists) { return (null, null); } var policy = new SharedAccessBlobPolicy() { SharedAccessStartTime = DateTime.UtcNow.AddMinutes(0), SharedAccessExpiryTime = DateTime.UtcNow.AddMinutes(3), Permissions = SharedAccessBlobPermissions.Read, }; var token = blob.GetSharedAccessSignature(policy, null, null, null, null); // IP制限 //var ipRange = new IPAddressOrRange("168.1.5.65"); //var ipRange = new IPAddressOrRange("168.1.5.60", "168.1.5.70"); //var token = blob.GetSharedAccessSignature(policy, null, null, null, ipRange); return (blob.Uri.AbsoluteUri, token); }
ログに出力される URI は :
が %3A
にエンコードされているので :
に戻すとそのままの URI でブラウザでアクセスできる。
SAS トークンの生成と同時に、受け取ったパラメータに応じて Blob のパスをサーバー側で決めることもできるため、SAS URI 自体を返すようにするとクライアントは Blob や対象のファイルなど詳細を知らなくてよくなる。