LoginSignup
2
1

More than 1 year has passed since last update.

Azure Functions にマネージド ID を割り当ててユーザー委任 SAS トークンを発行する

Last updated at Posted at 2021-04-04

やりたいこと

Azure Storage Account に一時的なアクセス権限を与える SAS トークンを発行するには、ストレージアカウントのキーをベースにするのではなく、user delegation SAS (ユーザー委任 SAS) がセキュリティ的に良さそうです。しかし、クライアントが Raspberry Pi など Azure 上にない場合は、ユーザー委任 SAS を発行するのにサービスプリンシパルの設定がややこしそうに思いました。

そこで、Azure Functions に マネージド ID を割り当ててユーザー委任 SAS トークンを発行できるようにしてみました。これにより、Azure Functions を呼び出すことで発行された SAS を取得できます。今度は Azure Functions 側のアクセス管理が問題になりますが、そこはまた別途検討しようと思います。

Azure Functions 側のコード

ユーザー委任 SAS を発行するための公式ドキュメントが .NET, Azure CLI, PowerShell しか見つからなかったため、今回は PowerShell のドキュメント に沿いました。なお、Azure Functions の Cold start の影響なのか、呼び出し間に時間が空くと応答に数十秒かかることもありました。いずれ他の言語でも試してみたいと思います。

using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request. Create SAS Uri."

$StorageAccountName = "<お使いのストレージアカウント名>"
$ContainerName = "<お使いのコンテナ名>"
$BlobName = $Request.Body.fileName

# https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-user-delegation-sas-create-powershell
$ctx = New-AzStorageContext -StorageAccountName $StorageAccountName -UseConnectedAccount

# https://docs.microsoft.com/ja-jp/powershell/module/az.storage/new-azstorageblobsastoken?view=azps-5.7.0#example-2--generate-a-blob-sas-token-with-life-time
$StartTime = Get-Date
$EndTime = $StartTime.AddHours(2.0)

if ($BlobName)
{
    $Uri = New-AzStorageBlobSASToken -Context $ctx `
        -Container $ContainerName `
        -Blob $BlobName `
        -Permission racwd `
        -StartTime $startTime `
        -ExpiryTime $EndTime `
        -FullUri
}
else
{
# Blob 単位の SAS を発行したい場合
# https://docs.microsoft.com/ja-jp/azure/storage/blobs/storage-blob-user-delegation-sas-create-powershell#create-a-user-delegation-sas-for-a-blob
    $Uri = New-AzStorageContainerSASToken -Context $ctx `
        -Name $ContainerName `
        -Permission racwdl `
        -ExpiryTime $EndTime `
        -FullUri
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = "{`"url`":`"" + $Uri + "`"}"
})

マネージド ID の割り当て

公式ドキュメント: ユーザーの委任 SAS の作成 - RBAC を使用してアクセス許可を割り当てる
に記載があるように、generateUserDelegationKey 権限および、発行した SAS に許可したい操作権限を持つ Azure ロールを割り当てる必要があります。

image.png

今回は組み込みロールの中から ストレージ BLOB データ共同作成者 を選びました。お使いのストレージアカウントに対して割り当てます。

image.png

アプリファイルの設定

前述のコードを利用するための設定が必要です。

requirementes.psd1 では Az モジュールを使えるようにします。

# This file enables modules to be automatically managed by the Functions service.
# See https://aka.ms/functionsmanageddependency for additional information.
#
@{
    # For latest supported version, go to 'https://www.powershellgallery.com/packages/Az'. 
    # To use the Az module in your function app, please uncomment the line below.
    'Az' = '5.*'
}

profile.ps1 では、Enable-AzureRmAlias を実行するようにします Azure.Storage モジュールはまだ AzureRm なのかな...?

profile.ps1
# Azure Functions profile.ps1
#
# This profile.ps1 will get executed every "cold start" of your Function App.
# "cold start" occurs when:
#
# * A Function App starts up for the very first time
# * A Function App starts up after being de-allocated due to inactivity
#
# You can define helper functions, run commands, or specify environment variables
# NOTE: any variables defined that are not environment variables will get reset after the first execution

# Authenticate with Azure PowerShell using MSI.
# Remove this if you are not planning on using MSI or Azure PowerShell.
if ($env:MSI_SECRET) {
    Disable-AzContextAutosave -Scope Process | Out-Null
    Connect-AzAccount -Identity
}

# Uncomment the next line to enable legacy AzureRm alias in Azure PowerShell.
Enable-AzureRmAlias

# You can also define functions or aliases that can be referenced in any of your PowerShell functions.

実行結果

Azure Functions の「関数の URL を取得」で取得した URL にアクセスして、SAS トークン付きの URL が返ってくることを確認しましょう。

{
  "url": "https://<ストレージアカウント名>.blob.core.windows.net/<コンテナ名>?<SAS トーコン>"
}

こちらのトークンをもとにマネージド ID に割り当たっている権限の操作が可能です。

おわりに

Cold Start の問題をまだ解消できていないですが、次は SORACOM Funk とも組み合わせることでデバイス <=> Azure Functions のアクセス問題を解決してみようかと思います。マネージド ID の使い方がわかってよかったです。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1