Azure Functions を使っていて気になるのが認証制御です。
AWS API Gateway + Lamdba では、任意の Token をつけることができました。それでは Azure Functions はどうでしょうか?
App Service Authentication/Authorization のような、アカウント連携はあまりに重厚でしょう。単純にAPI Keyで済ませたいものです。
そこで今回は Azure Functions で API Keyを使った認証について見てみましょう。
目次
API Key認証の例
API Key認証といってもどんなものでしょうか。
AWS
たとえば API Gateway では API Keys としてトークンを発行できます。
このトークンを任意のAPIで有効化することで、APIごとに認証トークンがヘッダにないとアクセスできないようにできます。
Azure Functions
翻って Azure Functions です。
Azure Functions を触っていて気づくのが、Github WebhookだけURL が違い/Github Secretを持つということです。
なんともわかりやすいでしょう。
Function 種類 | Function Url フォーマット | Github Secret | サンプル |
---|---|---|---|
Empty | なし | なし | |
Http Trigger | https://{function app name}.azurewebsites.net/api/{function name}?code={api key} |
なし | |
Generic Webhook | https://{function app name}.azurewebsites.net/api/{function name}?code={api key} |
なし | |
Github Webhook | `https://{function app name}.azurewebsites.net/api/{function name} |
{api key} |
API Key の詳細
ここ最近アップデートされたドキュメントに概要が説明されています。
You can use an HTTP or WebHook trigger to call a function in response to an HTTP request. The request must include an API key, which is currently only available in the Azure portal UI.
基本的には HTTP、WebHookトリガーのいずれもリクエストに API Key を含む必要があります。
さて API Key などの認証については、Function の設定に依ります。すなわち Function が HTTP Trigger なのか Webhook なのかということです。
Integrate タブから function.json を見てみましょう。
Advanced Editor から詳細の json を操作できます。例えば GenericWebhook なら次のとおりです。
{ "bindings": [ { "webHookType": "genericJson", "type": "httpTrigger", "direction": "in", "name": "req" }, { "type": "http", "direction": "out", "name": "res" } ], "disabled": false }
プロパティのの説明は、ドキュメントにあるとおりです。
HTTP Request のプロパティです。
プロパティ | Webhookトリガーの場合 | HTTPトリガーの場合 |
---|---|---|
name | Function コード内でリクエストオブジェクトを示す変数名として利用されます。*1res にしたならコードでも res として受けるということです。 |
同左 |
type | 必ず httpTrigger とします。 |
同左 |
direction | 必ずin とします。 |
同左 |
webHookType | 正当な入力値は github , slack , genericJson のいずれかです。 |
WebHook ではないのでこのプロパティを空文字"" とします。 |
authLevel | Webhookトリガーの場合無視され適用されません。 | API Keyについて制御できます。function とすることでAPI Keyを必須とできます。anonymous とすることで API Keyを無視します。admin とすることで、master API Key を必須とします。 |
HTTP Response のプロパティです。
プロパティ | 説明 |
---|---|
name | レスポンスオブジェクトを示す変数名です。req にしたならコードでも req で返す必要があります。 |
type | 必ず http とします。 |
direction | 必ず out とします。 |
API Key の保存場所
API Key は、D:\home\data\Functions\secrets
に保存されています。
Kudu で見てみましょう。
host.json
最も大事な master key は、host.json
に書かれています。
host.json に書かれた2つのキーを説明します。
キー | 説明 |
---|---|
masterkey | FunctionApp 内の全てのFunctionで利用できます。無効のFunctionもトリガー実行できません。 function.json で authLevel をadmin にすることで必須にできます。 |
functionkey | FunctionApp 内の全てのFunctionで利用できます。無効のFunctionはトリガー実行できません。 |
しかしこの host.json の鍵は権限が強すぎます。Wehook のプロバイダと共有なんてもっての他です。
もっと対象の Function だけに働きかけられる鍵はないでしょうか。
Functionごとの鍵
実際の利用を考えた場合、host.json ではなく、各ファンクションを作った際に自動的に生成される<Function名>.json
の鍵を使いましょう。例えば GenericWebhookCSharp1
というFunction を作成したらGenericWebhookCSharp1.json
がその鍵をもつファイルです。
この鍵の key プロパティの値が、対象Function を叩くための API Key です。
またこの鍵は、Functionを作成した時の Function Url
で、クエリストリングに埋め込まれています。
トリガーによるAPI Key 必須選択と渡し方
ドキュメントにある通りです。Wehook トリガーでは API Key は必須です。HTTP トリガーでは選択可能です。
To trigger a WebHook function the HTTP request must include an API key. For non-WebHook HTTP triggers, this requirement is optional.
API Key の埋め込み方
API Key は2つの埋め込み方があります。
code
という名前で、クエリストリングに含めるx-functions-key
という、HTTP リクエストヘッダに埋める*2
もちろんHTTPトリガーに関しては、function.json
で authLevel
を anonymous にすることで API Key がなくても問題なくできます。
簡単なメソッドで検証してみましょう。1つはクエリストリングでキーを渡します。もう1つはx-functions-key
ヘッダで渡します。
Webhook トリガー
HTTP Request は、API Key をクエリストリングで含んでいる必要があります。
クエリストリングにAPI Key がなかったり、間違っていると BadRequest
が返ります。
正しいAPI Key を含めると、jsonが判定されて応答が返ってきます。
また、ヘッダにx-functions-key
でキーを渡してもダメなのが特徴的です。
HTTP トリガー
API Key はオプショナルです。この指定を行うのが、先ほどの function.json の HTTP Request にある authLevel
プロパティです。
authLevel
が省略 or function
もしfunction.json で authLevel が省略された場合はfunction
相当、となるためAPI Key が必須となります。
クエリストリングにAPI Key がなかったり、間違っているとUnauthorized
が返ります。
クエリストリングに正しいAPI Key を含めると、jsonが判定されて応答が返ってきます。
Webhook と違い、ヘッダにx-functions-key
でキーを渡することでも認証ができます。
authLevel
が anonymous
匿名認証のためAPI Key は無視されます。URL さえ正しく叩ければいい状態です。
authLevel
が admin
host.json
のmasterKey 以外の鍵では呼べなくなります。host.json
のfunctionKey でも実行できません。
鍵の変更
もし API Key を変更したくなったどうしましょうか?
ドキュメントに記述がありませんが、D:\home\data\Functions\secrets
の鍵を書き換えれば更新されます。
変更前 :
変更後 :
変更が確認できましたね
まとめ
これに気づかず、独自ヘッダ認証を組み込んでからドキュメントが発行されました。
Azure functions で作成するとデフォルトで API Key が必須です。HTTPS であることからも、安全がある程度担保されているので、いい感じに扱えますね。
API の更新も含めて、うまく使う目処がそろそろ立つのではないでしょうか?