🔰

Azure API Management で認証・認可を学ぶ

2024/06/13に公開

APIを保護するための認証・認可の基本的な知識や、API利用時の実装のイメージをまとめました。
下記のAzure API Management での API への認証と認可のフロー図を補足したものになりますが、APIの認証機能を学ぼう!という方の参考になればと思います。

認証・認可とは

まずAPIへアクセスする際の「認証・認可」について説明します。

説明 認証 認可
目的 本人特定 アクセス制御
すること API にアクセスするユーザーまたはアプリの ID を確認 特定の API にアクセスするアクセス許可をユーザーまたはアプリが持っているかどうかを判別
代表的なプロトコル OpenID Connect (OIDC) OAuth 2.0
発行するもの IDトークン アクセストークン
トークンを発行するところ IDプロバイダー 認可サーバー

「認証」は普段よく耳にするパスワード認証や生体認証のように、誰であるかを確認します。

「認可」ではアクセス制御を行いますがその過程で「誰であるか」を知る必要があり、「認証」と同じような情報を必要とします。
その為、OpenID ConnectとOAuth 2.0は共によく使用され、OAuth 2.0の認証と認可サービス全体を提供するエンティティを認可プロバイダーと呼びます。

トークン発行元の補足
  • IDプロバイダー: ユーザーのアイデンティティを管理し、認証を提供するエンティティ。OAuth 2.0の文脈ではIDプロバイダーが認可サーバーの役割も果たすことが多い。
  • 認可サーバー: OAuth 2.0のトークン発行やトークン管理を行うサーバー。
  • 認可プロバイダー: 認可サーバーを含む、OAuth 2.0の認証と認可サービス全体を提供するエンティティ。

Azureでは認可プロバイダーの機能はMicrosoft Entra IDが担っています。


引用:OAuthとOpenID Connectについて~仕組みや特徴など解説~

IDトークンとアクセストークンの中身

IDトークンやアクセストークンは基本的には JWT(JSON Web Token)の仕様が用いられます。
JWTは「ヘッダー」「ペイロード」「署名」の3部分で構成されており、それぞれがBase64Urlでエンコードされています。
デコードするとユーザーのプロフィール情報や認証・認可における識別子を取得できます。

以下は、デコード前のアクセストークンの例です。
見やすくするために.ごとに改行していますが、中身はヘッダー.ペイロード.署名という構造になっています。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. //ヘッダー
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvbiBEb2UiLCJhZG1pbiI6dHJ1ZSwiZXhwIjoxNjIzNzM4MzE2LCJpYXQiOjE2MjM3MjEzMTZ9. //ペイロード
s5D1q7yPp7QZ4X8R5V8H8T7K3G9R0Q9R2K6I8L4J7M0 //署名

上記をデコードすると、中身は以下のようになります。

  • ヘッダー:署名で利用するアルゴリズムなどを定義します。

    {
      "alg": "HS256",
      "typ": "JWT"
    }
    
    • alg: トークンの署名アルゴリズム(この例ではHS256)
    • typ: トークンのタイプ(JWT)
  • ペイロード:保存したいデータの実態です。

    {
      "sub": "1234567890",
      "name": "Azunyan",
      "exp": 1623738316,  # 有効期限(UNIXタイムスタンプ)
      "iat": 1623721316   # 発行時間(UNIXタイムスタンプ)
    }
    
    • sub: トークンの主題(ユーザーIDなど)
    • name: ユーザーの名前
    • exp: トークンの有効期限
    • iat: トークンの発行時間
  • 署名:ヘッダーとペイロードを基にして秘密鍵で署名されたものです。

IDトークンとアクセストークンのJWTは、署名とヘッダーの構成は基本的に同じですが、ペイロードの内容は異なります。
ペイロードは「保存したいデータの実態」が入っている為、トークンの目的に応じた情報が含まれます。IDトークンはユーザーの認証情報、アクセストークンはリソースへのアクセス権の情報です。

以上が認証・認可のために必要な基本情報になります。
では、APIの認可のながれについてみていきましょう。

API Managementの認可シナリオ

API Managementの一般的な認可シナリオは、呼び出し元のアプリケーションがバックエンドへのアクセスを直接要求し、Authorization ヘッダーの OAuth 2.0 トークンをゲートウェイに提示する方法です。

下記は、認可プロバイダーとしてMicrosoft Entra IDを使用し、APIゲートウェイとしてAzure API Managementを使用した際の認可フロー図です。

引用:Azure API Management での API への認証と認可

各コンポーネントの役割を簡単に補足します。

  1. ブラウザ(Browser)
    エンドユーザーが操作するインターフェースです。ユーザーはブラウザを通じてウェブアプリケーションにアクセスします。
  2. クライアントアプリケーション(Client App)
    ブラウザ内で動作するウェブアプリケーションです。ユーザーインターフェースを提供し、API Managementを通じてバックエンドAPIにリクエストを送信します。
  3. API Management
    クライアントアプリケーションからのリクエストを受け取り、適切なBackendに転送する役割を持ちます。セキュリティ、レート制限、キャッシングなどのポリシーを適用します。
  4. バックエンドAPI(Backend API)
    実際のデータ処理やビジネスロジックを実行するサーバー側のAPIです。データベースや他のサービスと連携して、クライアントアプリケーションに必要なデータや機能を提供します。

認可シナリオの実装例

以下は、OAuth 2.0 トークンを使用してバックエンドにアクセスするためのサンプルコードです。
この例では、JavaScriptを使用してクライアントサイドからAzureのAPI Managementを介してバックエンドにリクエストを送信します。

前提条件

  • OAuth 2.0 トークンを取得済み
  • API ManagementのエンドポイントURLを知っている
  • 必要に応じて、CORS設定が適切に構成されている

サンプルコード

1. JavaScript (クライアントサイド)
// OAuth 2.0 トークン(例としてハードコードされていますが、通常は動的に取得します)
const accessToken = 'YOUR_OAUTH2_ACCESS_TOKEN';

// API ManagementのエンドポイントURL
const apiEndpoint = 'https://api-management.example.com/your-backend-api';

async function callBackendApi() {
    try {
        const response = await fetch(apiEndpoint, {
            method: 'GET', // または 'POST', 'PUT', 'DELETE' など
            headers: {
                'Authorization': `Bearer ${accessToken}`,
                'Content-Type': 'application/json'
            }
        });

        if (!response.ok) {
            throw new Error(`HTTP error! status: ${response.status}`);
        }

        const data = await response.json();
        console.log('Response from backend API:', data);
    } catch (error) {
        console.error('Error calling backend API:', error);
    }
}

// ボタンなどのイベントハンドラから呼び出す
document.getElementById('callApiButton').addEventListener('click', callBackendApi);
2. HTML (クライアントサイド)
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>API Management 呼び出しサンプル</title>
</head>
<body>
    <button id="callApiButton">バックエンドAPIを呼び出す</button>
    <script src="path/to/your/javascript-file.js"></script>
</body>
</html>

説明

  1. JavaScriptコード:

    • accessTokenには事前に取得したOAuth 2.0トークンを代入します。
    • apiEndpointにはAPI ManagementのエンドポイントURLを設定します。
    • fetch関数を使用してAPI Managementにリクエストを送信します。AuthorizationヘッダーにBearerトークンを設定し、Content-Typeapplication/jsonに設定します。
    • レスポンスを受け取り、JSON形式でパースしてコンソールに出力します。
    • エラーハンドリングも行います。
  2. HTMLコード:

    • ボタンを配置し、クリックイベントでJavaScriptの関数を呼び出します。
    • JavaScriptファイルを読み込むための<script>タグを追加します。

このコードを実行すると、ユーザーがボタンをクリックするときにAPI Managementを介してバックエンドが呼び出され、レスポンスがコンソールに表示されます。

まとめ

  • 認証・認可とは
  • APIゲートウェイ(Azure API Management)の認可フローについて
  • 認可シナリオの実装例

についてまとめてきました。
どなたかの参考になれば幸いです。
以上、えみり〜でした|ωΦ)ฅ

参考

Discussion