OAuth 2.0 Basics

前書き

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

前提条件:

コンポーネント

一般的な OAuth 2.0 アーキテクチャには、以下のフロー図に示すように、複数のコンポーネントが含まれます。このチュートリアルでは、Authlete 管理コンソール と、米国リージョンで稼働する Authlete API クラスター (https://us.authlete.com) のパブリッククラウドバージョンを使用します。認可サーバーおよびリソースサーバーは curl コマンドを使用してシミュレートし、認可、トークン発行、およびイントロスペクションのために 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 を呼び出すために必要なサービスアクセストークンを生成してください。このチュートリアルでは、米国クラスターでサービスを作成し、クライアントを設定したものと仮定します。

項目
Authlete API - 米国クラスター https://us.authlete.com
サービス ID 自動生成, 例: 933860280
サービスアクセストークン 自動生成, 例: DL7jo1z3-iUIXyI5MnX...
クライアント ID 自動生成, 例: 12818600553323
クライアントシークレット 自動生成
クライアントタイプ CONFIDENTIAL
リダイレクト URI https://client.example.org/cb/example.com
クライアント認証方法 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 12818600553323
response_type code
redirect_uri https://client.example.org/cb/example.com

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

redirect_uri=https://client.example.org/cb/example.com
 &response_type=code
 &client_id=12818600553323

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

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

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

以下の curl コマンドを使用して Authlete API に認可リクエストを行います(ステップ 5)。

# Linux/Mac
curl -X POST "https://us.authlete.com/api/933860280/auth/authorization" \
     -H "Authorization: Bearer $sat" \
     -H "Content-Type: application/json" \
     -d '{ "parameters": "response_type=code&client_id=4111796580&redirect_uri=https://client.example.org/cb/example.com"}'

# Windows
curl.exe -X POST "https://us.authlete.com/api/933860280/auth/authorization" `
     -H "Authorization: Bearer $env:sat" `
     -H "Content-Type: application/json" `
     -d '{ "parameters": "response_type=code&client_id=4111796580&redirect_uri=https://client.example.org/cb/example.com"}'

注意:

  • $sat を実際のベアラートークンに置き換えてください。
  • Windows では、環境変数($env:sat)を扱うために PowerShell を使用してください。

リクエストが有効である場合、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 に共有する識別子が john.s@example.com であると判断しました。
  • 認可サーバーはリソース所有者の同意を得ました。

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

以下の curl コマンドを使用して Authlete API に認可リクエストを発行します。

# Linux/Mac
curl -X POST "https://us.authlete.com/api/933860280/auth/authorization/issue" \
     -H "Authorization: Bearer $sat" \
     -H "Content-Type: application/json" \
     -d '{ "ticket": "5tqii9i_pUp1iteacZGUtdjikRnqGSrPwW7lqoH1Pcc","subject": "testuser01"}'

# Windows
curl.exe -X POST "https://us.authlete.com/api/933860280/auth/authorization/issue" `
     -H "Authorization: Bearer $env:sat" `
     -H "Content-Type: application/json" `
     -d '{ "ticket": "5tqii9i_pUp1iteacZGUtdjikRnqGSrPwW7lqoH1Pcc","subject": "testuser01"}'

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

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

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

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

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

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

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

トークンリクエスト

ここでは、ユーザーエージェントが認可サーバーからのリダイレクト応答を受信したものと仮定します。その後、以下のようなリクエストがクライアントに送信されます(ステップ 13)。(可読性のため折り返しを追加しています)

GET /cb/example.com?code=tJlGEKt8y0DLpjIA_jweywRtJs2fh83ZGNiwFRmIwYI HTTP/1.1
Host: client.example.org

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

POST /token HTTP/1.1
Host: as.example.com
Authorization: Basic base64(12818600553323:-olDIKD9BihRfB8O1JxobUEKBZ7PIV5Z6oaqxAshmoUtUZgB-wjmmxTYDiDV6vM_Mgl267PeNrRftq8cWplvmg)
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code
 &code=tJlGEKt8y0DLpjIA_jweywRtJs2fh83ZGNiwFRmIwYI
 &redirect_uri=https://client.example.org/cb/example.com

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

以下の curl コマンドを使用し、Authlete API を介して認可コードをアクセストークンに交換します。

# Linux/Mac
curl -X POST "https://us.authlete.com/api/933860280/auth/token" \
     -H "Authorization: Bearer $sat" \
     -H "Content-Type: application/json" \
     -d '{ "clientId": "2800496004","clientSecret": "AqZKLbUFfRurwZ0-zN1BwAXfo-odPwrZa6XoSOrm-AKtbaaOAq6uzWM3oVG4w","parameters": "grant_type=authorization_code&code=tJlGEKt8y0DLpjIA_jweywRtJs2fh83ZGNiwFRmIwYI&redirect_uri=https://client.example.org/cb/example.com" }'


# Windows
curl.exe -X POST "https://us.authlete.com/api/933860280/auth/token" `
     -H "Authorization: Bearer $sat" `
     -H "Content-Type: application/json" `
     -d '{ "clientId": "2800496004","clientSecret": "AqZKLbUFfRurwZ0-zN1BwAXfo-odPwrZa6XoSOrm-AKtbaaOAq6uzWM3oVG4w","parameters": "grant_type=authorization_code&code=tJlGEKt8y0DLpjIA_jweywRtJs2fh83ZGNiwFRmIwYI&redirect_uri=https://client.example.org/cb/example.com" }'

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

{
    "accessToken": "gV5ByjqCVjyinFugV9Wlc0oAxkEP0osifSajXSfJV9g",
    "accessTokenDuration": 86400,
    "accessTokenExpiresAt": 1730203012061,
    "action": "OK",
    "clientAuthMethod": "CLIENT_SECRET_BASIC",
    "clientId": 2800496004,
    "grantType": "AUTHORIZATION_CODE",
    "refreshToken": "1mQRm2XRwaBNYRIjxjO0ls9hb4eDKo9I3ChU0yy8lHo",
    "refreshTokenDuration": 864000,
    "refreshTokenExpiresAt": 1730980612061,
    "responseContent": "{\"access_token\":\"gV5ByjqCVjyinFugV9Wlc0oAxkEP0osifSajXSfJV9g\",\"token_type\":\"Bearer\",\"expires_in\":86400,\"scope\":null,\"refresh_token\":\"1mQRm2XRwaBNYRIjxjO0ls9hb4eDKo9I3ChU0yy8lHo\"}",
    "resultCode": "A050001",
    "resultMessage": "[A050001] トークンリクエスト (grant_type=authorization_code) が正常に処理されました。",
    "subject": "john.s@example.com",
}
  • 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 は、この目的のために /auth/introspection API を提供しています。この API はトークンの有効性を検証し、必要な情報を提供します。

以下の curl コマンドを使用して、Authlete API を介してトークンをイントロスペクトします。

# Linux/Mac
curl -X POST "https://us.authlete.com/api/933860280/auth/introspection" \
     -H "Authorization: Bearer $sat" \
     -H "Content-Type: application/json" \
     -d '{ "token": "gV5ByjqCVjyinFugV9Wlc0oAxkEP0osifSajXSfJV9g" }'

# Windows
curl.exe -X POST "https://us.authlete.com/api/933860280/auth/introspection" `
     -H "Authorization: Bearer $env:sat" `
     -H "Content-Type: application/json" `
     -d '{ "token": "gV5ByjqCVjyinFugV9Wlc0oAxkEP0osifSajXSfJV9g" }'

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

{
    "action": "OK",
    "authTime": 0,
    "clientId": 2800496004,
    "expiresAt": 1730203012000,
    "grantType": "AUTHORIZATION_CODE",
    "issuableCredentials": null,
    "properties": null,
    "refreshable": true,
    "resources": null,
    "responseContent": "Bearer error=\"invalid_request\"",
    "resultCode": "A056001",
    "resultMessage": "[A056001] アクセストークンは有効です。",
    "scopeDetails": null,
    "scopes": null,
    "serviceAttributes": null,
    "subject": "john.s@example.com",
    "sufficient": false,
    "usable": true
}

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

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

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

まとめ

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

次のステップ

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