OAuth 2.0 Basics

はじめに

このチュートリアルでは、OAuth 2.0 の認可コードグラントフローをサポートする認可サーバーを実装するために Authlete API を使用する基本的な方法を説明します。また、リソースサーバーがアクセス トークンを迅速に検証し、安全で認可された API へのアクセスを提供するために Authlete API を使用する方法も示します。

前提条件:

コンポーネント

一般的な OAuth 2.0 アーキテクチャには、以下のフロー図に示すように、複数のコンポーネントが含まれます。このチュートリアルでは、Authlete 管理コンソール と、米国リージョンで稼働する Authlete API クラスター (https://us.authlete.com) のパブリッククラウドバージョンを使用します。認可サーバーおよびリソースサーバーは curl コマンド (もしくは API エクスプローラー) を使用してシミュレートし、認可、トークン発行、およびイントロスペクションのために Authlete へ API リクエストを行う方法を示します。

flowchart LR subgraph EndUser [エンドユーザー] userAgent["ユーザーエージェント (N/A)"] resourceOwner["リソース所有者 (N/A)"] end subgraph APIClient [API クライアント] client["クライアント (N/A)"] end subgraph APIServer [API サーバー] authServer["認可サーバー (curl)"] resourceServer["リソースサーバー (curl)"] authAdmin["Authlete 管理者"] end subgraph Authlete [Authlete] mgmtConsole["Authlete 管理コンソール"] authAPI["Authlete API"] end resourceOwner --> userAgent userAgent -- "クライアントへのアクセス" --> client userAgent -- "認可リクエスト (ユーザー認証と同意)" --> authServer client -- "トークンリクエスト" --> authServer client -- "APIリクエスト" --> resourceServer %% API サーバーと Authlete のやり取り authAdmin -- "サービス/クライアント管理" --> mgmtConsole mgmtConsole -- "APIリクエスト" --> authAPI authServer -- "APIリクエスト" --> authAPI resourceServer -- "APIリクエスト" --> authAPI

各コンポーネントの FQDN は以下の通りです。認可サーバーおよびクライアントは curl でシミュレーションするため実際には FQDN は利用されませんが、以下の値を使用して OAuth フローを説明します。

コンポーネント FQDN
Authlete API クラスター (米国) us.authlete.com
Authlete 管理コンソール console.authlete.com
認可サーバー as.example.com
クライアント client.example.org
リソースサーバー N/A

環境セットアップ

クイックスタート、およびクライアントの作成に従って、新しい Authlete サービスとクライアントを作成してください。そして、プロパティの値を以下のフィールドに入力してください。

項目
Authlete API
サービス ID
サービスアクセストークン
クライアント ID
クライアントシークレット
クライアントタイプ 機密 (既定値)
リダイレクト URI
クライアント認証方法 CLIENT_SECRET_BASIC (既定値)

ウォークスルー

以下のシーケンス図は、このチュートリアルで使用される OAuth 2.0 フロー全体を示しています。各ステップを進める際に参照してください。

sequenceDiagram autonumber participant RO as リソース所有者 participant UA as ユーザーエージェント participant C as クライアント participant AS as 認可サーバー participant RS as リソースサーバー participant API as Authlete API RO ->> UA: 開始 UA ->> C: リクエストを実行 C -->> UA: 認可リクエスト UA ->> AS: リクエストを転送 AS ->> API: POST /auth/authorization API -->> AS: 処理可否結果
(チケットを含む) AS -->> UA: ユーザー認証および同意ページ RO <<->> UA: 認証情報を入力 UA ->> AS: ログインおよび同意 AS ->> API: POST /auth/authorization/issue
(チケットを含む) API -->> AS: 認可応答内容
(認可コードを含む) AS -->> UA: 認可応答 UA ->> C: 応答を転送 C ->> AS: トークンリクエスト
(認可コードを含む) AS ->> API: POST /auth/token API -->> AS: トークン応答内容
(アクセストークンを含む) AS -->> C: トークン応答 C ->> RS: 保護されたリソースへのアクセス
(アクセストークンを含む) RS ->> API: POST /auth/introspection API -->> RS: トークン検証応答 RS -->> C: クライアントへの応答 C -->> UA: コンテンツ UA -->> RO: 終了

認可リクエストの処理

クライアントは、ユーザーエージェントを介して認可サーバーに認可リクエストを行います(ステップ 3 および 4)。
このチュートリアルでは、以下の値がリクエストのパラメータとして指定されているものと仮定します。

パラメータ
client_id
response_type code
redirect_uri

上記例では認可サーバーがユーザーエージェントから以下のような HTTP GET クエリ文字列を受け取ることが期待されます。(可読性のため折り返しを追加しています。)


一般的な認可サーバーは、以下のルールを評価してから認可コードグラントフローを進める必要があります。

  • クライアント ID に関連付けられたクライアントが認可サーバーに登録されていることを確認する。
  • リダイレクト URI がクライアントに登録された URI のいずれかと一致することを確認する。
  • response_typescope などの他のパラメータ値がクライアントによってリクエスト内で指定されることが許可されていることを確認する。

Authlete の Process Authorization Request API (/auth/authorization) は、認可サーバーに代わってこれらのリクエスト検証を実行します。

以下のように、Authlete API にリクエストを送信します(ステップ 5)。

  • curl コマンド (For Linux/Mac)

  • curl コマンド (For Windows (PowerShell 5.1))

  • curl コマンド (For Windows (PowerShell 7))

  • API エクスプローラー (/auth/authorization)
    • サービス ID (serviceId):

リクエストが有効である場合、Authlete は以下のような応答を返します(ステップ 6)。

{
    "action": "INTERACTION",
    "resultCode": "A004001",
    "resultMessage": "[A004001] Authlete has successfully issued a ticket to the service (API Key = 933860280) for the authorization request from the client (ID = 2800496004). [response_type=code, openid=false]",
    "ticket": "cElOaH9j4mS6AiIGR9oLqHlDn9jpvcNjqSgyRqfcmAE",
    "client": {...},
    "service": {...},
}
  • resultMessage は、リクエスト処理の結果を人間が読める形式で提供します(詳細は Authlete の結果コードの解釈 を参照)。
  • action は、認可サーバーが次に何を行うべきかを示します。
  • ticket は、次のステップで別の API にリクエストを行うために認可サーバーが必要とする値です。

Authlete はまた、応答内でサービスおよびクライアント情報を提供します。認可サーバーはこれを利用して、リソース所有者にクライアントがサービスへのアクセスを許可するかどうかを尋ねます。

ユーザー認証とアクセス許可の確認

リソース所有者と認可サーバーの間の実際のやり取りは、このチュートリアルの範囲外です。通常、認可サーバーはユーザーの資格情報(例: ID とパスワード)を使用してユーザーを認証し、ユーザーの役割や権限を特定し、クライアントにアクセスを許可するかどうかを尋ねます(ステップ 7、8、9)。

認可コードの発行

認可サーバーが次の状態に達したと仮定します。

  • 認可サーバーはリソース所有者を認証し、subject パラメーター(Authlete に共有するユーザー識別子)の値が testuser01 であると判断しました。
  • 認可サーバーはリソース所有者の同意を得ました。

認可サーバーは次に、Authlete の Issue Authorization Response API (/auth/authorization/issue) にリクエストを行い、認可コードを発行します。この際、subject および /auth/authorization API 応答の ticket の値をリクエストパラメータとして含めます(ステップ 10)。

ここでは、ユーザーエージェントが認可サーバーから、以下の値を含むリダイレクト応答を受信したものと仮定します。

項目
ticket (チケット)
subject (識別子)

以下のように、Authlete API にリクエストを送信します。

  • curl コマンド (For Linux/Mac)

  • curl コマンド (For Windows (PowerShell 5.1))

  • curl コマンド (For Windows (PowerShell 7))

  • API エクスプローラー (/auth/authorization/issue)
    • サービス ID (serviceId):

リクエストが有効である場合、Authlete は以下のような応答を生成します(ステップ 11)。

{
  "action": "LOCATION",
  "responseContent": "https://client.example.org/cb/example.com?code=NGZf_ZTZdgGBg4WCNe45VGYHRpwoblJIYXFvRE1j-xE&iss=https%3A%2F%2Fauthlete.com",
  "accessTokenExpiresAt": 0,
  "accessTokenDuration": 0,
  "authorizationCode": "NGZf_ZTZdgGBg4WCNe45VGYHRpwoblJIYXFvRE1j-xE",
  "ticketInfo": {},
  "resultCode": "A040001",
  "resultMessage": "[A040001] The authorization request was processed successfully."
}
  • resultMessage は、リクエスト処理の結果を人間が読める形式で提供します(詳細は Authlete の結果コードの解釈 を参照)。
  • action は、認可サーバーが次に何を行うべきかを示します。この応答では LOCATION という値が指定されており、認可サーバーはユーザーエージェントにリダイレクト応答を返す必要があります。
  • responseContent は、認可サーバーから返却する認可レスポンスの内容を表します。

認可サーバーは以下のような応答をユーザーエージェントに送信することが期待されます(ステップ 12)。

HTTP/1.1 302 Found
Location: https://client.example.org/cb/example.com
 ?code=tJlGEKt8y0DLpjIA_jweywRtJs2fh83ZGNiwFRmIwYI

クライアントにトークンを発行しない場合の状況もあります。たとえば、前の認証やユーザーの同意確認の結果、またはトークン発行を妨げるその他の文脈が欠落している場合です。このような場合、認可サーバーはプロトコル応答を通じて認可フローが終了したことをクライアントに通知する必要があります。

Authlete の Fail Authorization Request API (/auth/authorization/fail) は、クライアントに送信されるメッセージや応答の転送方法に関する終了プロセスをサポートします。

要約すると、認可サーバーは通常、ユーザー認証および同意の結果に応じて /auth/authorization/issue または /auth/authorization/fail API のいずれかにリクエストを送信します。

トークンリクエストの処理

ここでは、ユーザーエージェントが認可サーバーから、以下の値を含むリダイレクト応答を受信したものと仮定します。

項目
code (認可コード)

その後、以下のようなリクエストがクライアントに送信されます(ステップ 13)。(可読性のため折り返しを追加しています)


クライアントは code パラメータの値を抽出し、この値を使用してトークンリクエストを作成し、以下のように認可サーバーに送信します。このチュートリアルでは、https://as.example.com/token をトークンエンドポイント URI と仮定します(ステップ 14)。(可読性のため折り返しを追加しています。)


認可サーバーはリクエスト内のパラメータを評価し、その後、クライアントにトークン応答を返します。
このチュートリアルでは、Authlete の Process Token Request API (/auth/token) を使用してリクエストを評価し、応答を生成します。

以下のように、Authlete API にリクエストを送信します。

  • curl コマンド (For Linux/Mac)

  • curl コマンド (For Windows (PowerShell 5.1))

  • curl コマンド (For Windows (PowerShell 7))

  • API エクスプローラー (/auth/token)
    • サービス ID (serviceId):

リクエストが有効である場合、Authlete は以下のような応答を返します(ステップ 16)。

{
  "action": "OK",
  "responseContent": "{\"access_token\":\"ncizWUi41PvIx4Ao9dL4OzNTIvLARgm1lS56Sxzos0A\",\"token_type\":\"Bearer\",\"expires_in\":86400,\"scope\":null,\"refresh_token\":\"3WzZKis5wDyAmmq5v4xr8Rtyw8NQxR1pfmkyWpuDq70\"}",
  "accessToken": "ncizWUi41PvIx4Ao9dL4OzNTIvLARgm1lS56Sxzos0A",
  "accessTokenExpiresAt": 1771998433882,
  "accessTokenDuration": 86400,
  "refreshToken": "3WzZKis5wDyAmmq5v4xr8Rtyw8NQxR1pfmkyWpuDq70",
  "refreshTokenExpiresAt": 1772776033882,
  "refreshTokenDuration": 864000,
  "grantType": "AUTHORIZATION_CODE",
  "clientId": 1449670235,
  "clientIdAlias": "1449670235",
  "clientIdAliasUsed": true,
  "clientEntityIdUsed": false,
  "metadataDocumentUsed": false,
  "subject": "testuser01",
  "clientAuthMethod": "CLIENT_SECRET_BASIC",
  "previousRefreshTokenUsed": false,
  "cnonceExpiresAt": 0,
  "cnonceDuration": 0,
  "resultCode": "A050001",
  "resultMessage": "[A050001] The token request (grant_type=authorization_code) was processed successfully."
}
  • resultMessage は、リクエスト処理の結果を人間が読める形式で提供します(詳細は Authlete の結果コードの解釈 を参照)。
  • action は、認可サーバーが次に何を行うべきかを示します。この応答では OK という値が指定されており、認可サーバーはクライアントにトークン応答を送信する必要があります。
  • responseContent には、認可サーバーからの応答内容が含まれています。

認可サーバーは以下のような応答をクライアントに送信することが期待されます(ステップ 17)。

HTTP/1.1 200 OK
Content-Type: application/json

{
  "access_token":"gV5ByjqCVjyinFugV9Wlc0oAxkEP0osifSajXSfJV9g",
  "refresh_token":"1mQRm2XRwaBNYRIjxjO0ls9hb4eDKo9I3ChU0yy8lHo",
  "scope":null,
  "token_type":"Bearer",
  "expires_in":86400
}

認可サーバーはこれでトークンを正常に作成し、クライアントに提供しました。Authlete API を利用することで、認可サーバーは認可およびトークンリクエストのパラメータを評価するための複雑なロジックを実装する必要がなくなり、適切な方法で応答することができます。

API リクエスト(トークンイントロスペクション)

通常、クライアントはアクセストークンを使用してリソースサーバーにリクエストを送信し、API にアクセスします(ステップ 18)。リソースサーバーは、トークンの有効性を評価し、トークンに関連付けられたユーザーおよびクライアントに関する情報を取得し、API リクエストへの応答方法を決定します。

Authlete は、この目的のために Process Introspection Request API (/auth/introspection) を提供しています。この API はトークンの有効性を検証し、必要な情報を提供します。

ここでは、リソースサーバーがクライアントから、以下の値を含む API リクエストを受信したものと仮定します。

項目
access_token (アクセストークン)

以下のように、Authlete API にリクエストを発行します。

  • curl コマンド (For Linux/Mac)

  • curl コマンド (For Windows (PowerShell 5.1))

  • curl コマンド (For Windows (PowerShell 7))

  • API エクスプローラー (/auth/introspection)
    • サービス ID (serviceId):

リクエストが有効である場合、Authlete は以下のような応答を返します(ステップ 20)。

{
  "action": "OK",
  "clientId": 1449670235,
  "subject": "testuser01",
  "existent": true,
  "usable": true,
  "sufficient": false,
  "refreshable": true,
  "responseContent": "Bearer error=\"invalid_request\"",
  "expiresAt": 1771998434000,
  "clientIdAlias": "1449670235",
  "clientIdAliasUsed": true,
  "clientEntityIdUsed": false,
  "metadataDocumentUsed": false,
  "forExternalAttachment": false,
  "authTime": 0,
  "grantType": "AUTHORIZATION_CODE",
  "forCredentialIssuance": false,
  "cnonceExpiresAt": 0,
  "responseSigningRequired": false,
  "resultCode": "A056001",
  "resultMessage": "[A056001] The access token is valid."
}

リソースサーバーは、この応答から以下のような情報を取得できます。

  • トークンの有効期限(expiresAt
  • アクセスを承認したユーザーの識別子(subject
  • トークンを取得するために使用されたグラントタイプ(grantType
  • クライアント識別子(clientId

リソースサーバーはこれらの情報を使用して、API リクエストへの応答方法を決定します(ステップ 21)。

まとめ

このチュートリアルでは、Authlete API を使用して認可コードグラントフローを認可サーバーに実装する方法を説明しました。Authlete API によって、認可サーバーは複雑なロジックを実装することなく、認可およびトークンリクエストを正確に評価し適切な応答を生成できます。

次のステップ

Authlete の以下の機能をさらに探索してみましょう。