web-dev-qa-db-ja.com

Azure Functionsの認証

過去24時間、Azure Functionsの作成方法についてすべて読んで、MVC WebApiを複数の機能を持つ新しいFunction Appに正常に変換しました。私の問題は、最も基本的な認証を行う方法に関する明確なドキュメントやチュートリアルが見つからないことです。

私のシナリオは非常に単純です。 AADでユーザーをプロビジョニングし、それらのユーザーに特定の機能へのアクセスを許可します。 WebサイトのユーザーはUI要素をクリックして、Azure Functionsを呼び出すJavascriptをトリガーします。関数では、SQLインスタンスとやり取りする他の関数にそれを渡すため、何らかの方法でIDを確認できる必要があります。

誰かが私にこれを達成する方法を示すドキュメント、記事、例、何かを教えてもらえますか?

ポータルで機能アプリの「認証」設定を見つけ、認証プロバイダーとしてAADを選択したレコードについて。 Function Appを追加し、数人のユーザーをプロビジョニングしました。その後、次のテスト関数を作成しました。

[FunctionName("GetThings")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.User, "GET", Route = null)]HttpRequestMessage req, TraceWriter log)
{
    log.Info("Getting all the things");
    var identity = ClaimsPrincipal.Current.Identity;

    return identity.IsAuthenticated ?
        req.CreateResponse(HttpStatusCode.Unauthorized, "Not authenticated!") :
        req.CreateResponse(HttpStatusCode.OK, $"Hi {identity.Name}!");
}

現在、エンドポイントに直接アクセスしようとすると、ログインページにリダイレクトされます...その部分が機能していると思います。ユーザートークンを生成/取得する方法、リクエストに応じて関数に送信する方法、サーバー上で処理する方法は明確ではありません。

助けて?

19
ThatCreole

ユーザーがAzure ADで認証されると、AppServiceAuthSessoin Cookieが表示されます。これは不透明なCookieですが、呼び出してクレームと交換できます

https://yourFunctionApp.azurewebsites.net/.auth/me

Cookieヘッダーとして不透明Cookieを渡します。さらに、返されるid_tokenは、Bearerトークンとして使用するのに適しています。

実際、それはちょうど私に見える、私はそれを無記名者として実際にテストしていないので、少し注意が必要です。

Get claims

このメカニズムはEasy Authと呼ばれ、Googleにとってその名前のほうが簡単です。

トークンストアの詳細はこちら—
https://cgillum.tech/2016/03/07/app-service-token-store/

...これは、ユーザーのブラウザーから入ってくるHTTPヘッダーを読み取るだけでクレームを取得できるということです。

トークンへのアクセス

バックエンドコード内から、これらのトークンへのアクセスは、HTTP要求ヘッダーを読み取るのと同じくらい簡単です。ヘッダーにはX-MS-TOKEN-{provider}-{type}のような名前が付けられます。可能なトークンヘッダー名は以下のとおりです。

Azure Active Directoryトークンリクエストヘッダー:

X-MS-TOKEN-AAD-ID-TOKEN
X-MS-TOKEN-AAD-ACCESS-TOKEN
X-MS-TOKEN-AAD-EXPIRES-ON
X-MS-TOKEN-AAD-REFRESH-TOKEN

私は実際にちょうど今それを見つけたので、質問をありがとう!

更新:

私の考えは正しかった、id_tokenはBearerとしても良い:

$ curl -isk https://{funcApp}.azurewebsites.net/api/{someFunc} \
       -H "Authorization: Bearer eyJ0eXAiOi....oEU-Q"

HTTP/1.1 200 OK
Cache-Control: no-cache
Server: Microsoft-IIS/8.0
...

クレームを読み取る2つの方法(ヘッダーの読み取りと、ユーザーのCookieを使用したバックエンドからの/.auth/meの呼び出し)の主な違いは、取得する詳細の量です。後者にはさらに多くの方法があります。

Twitter認証済みユーザーのEasy Authから取得するheadersのセットは次のとおりです。

{
   "cookie": "AppServiceAuthSession=Lx43...xHDTA==",
   ...
   "x-ms-client-principal-name": "evilSnobu",
   "x-ms-client-principal-id": "35....",
   "x-ms-client-principal-idp": "Twitter",
   "x-ms-token-Twitter-access-token": "35...Dj",
   "x-ms-token-Twitter-access-token-secret": "OK3...Jx",
}

/.auth/meを呼び出して取得したクレーム:

{
   "access_token": "35...FDj",
   "access_token_secret": "OK3...sJx",
   "provider_name": "Twitter",
   "user_claims": [
      {
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
         "val": "352660979"
      },
      {
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn",
         "val": "evilSnobu"
      },
      {
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
         "val": "Safarihat Hacker"
      },
      {
         "typ": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/webpage",
         "val": "..."
      },
      {
         "typ": "urn:Twitter:description",
         "val": "GENIUS. HAVE BRAIN. WILL TRAVEL."
      },
      {
         "typ": "urn:Twitter:location",
         "val": ""
      },
      {
         "typ": "urn:Twitter:time_zone",
         "val": "London"
      },
      {
         "typ": "urn:Twitter:lang",
         "val": "en"
      },
      {
         "typ": "urn:Twitter:verified",
         "val": "False"
      },
      {
         "typ": "urn:Twitter:profile_image_url_https",
         "val": "https://pbs.twimg.com/profile_images/867473646876545024/1elebfK1_normal.jpg"
      }
   ],
   "user_id": "evilSnobu"
}
13
evilSnobu

Azure Functions v2の小さな拡張機能を作成しました。この拡張機能は、ベアラートークンを使用する場合に役立ちます。

たとえば、アプリへの匿名リクエストを許可する場合、Azure B2Cを使用します。

したがって、ボイラープレートを使用せずに、Azure FunctionでClaimsPrincipalの権利を取得できます。

[FunctionName("Example")]
public async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", Route = null)] HttpRequest req,
    [FunctionToken] FunctionTokenResult token,
    ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");
    return (ActionResult) new OkObjectResult($"Hello, {token}");
}

コードは Github に投稿されます

0
user9035756