Table of Contents
このドキュメントは、Authlete APIs を使用して、認可コードフロー をサポートする OpenID Connect (OIDC) アイデンティティプロバイダー (IdP) サーバーを実装する基本的な使用方法を説明するためのチュートリアルです。
このチュートリアルを完了すると、以下を実施できます:
一般的な Authlete の実装では、認可サーバーのミドルウェアが Authlete API へのリクエストの送信およびレスポンスの処理を担当します。このチュートリアルでは、bash/zsh の curl
コマンドを使用してこれらのリクエストを直接行います。もちろん、PowerShell や Postman など、別の HTTP クライアントを使用することもできますが、その場合は手順を適宜調整する必要があります。
この OAuth フロー内で各コンポーネントがどのように連携するかを理解するために、各コンポーネントの完全修飾ドメイン名 (FQDN) を以下に示します。認可サーバーとクライアントの FQDN は参考用に作成されたものであり、実際の実装では適切な値に置き換える必要があります
コンポーネント | FQDN |
---|---|
Authlete API US Cluster | us.authlete.com |
Authlete 管理コンソール | console.authlete.com |
認可サーバー | as.example.com |
クライアント | client.example.org |
リソースサーバー | N/A |
Authlete API サービスを作成し、サービスにクライアントを登録する方法については、「Authlete のサインアップとサービスの作成」を参照してください。
サービス ID, サービス アクセストークン, そしてクライアントシークレットの値を書き留めるのを忘れないようにしてください。
すでに他の Authlete チュートリアルを完了している場合、既存のサービスを再利用できます。そうでない場合は、以下の値を使用してサービスを作成し、他のすべてのフィールドはデフォルトのままにしてください。
フィールド | 値 |
---|---|
API クラスター | 🇺🇸 US |
サービス名 | Demo AS |
サービスの詳細情報 | Example authorization service |
以下の値を使用してクライアントを作成し、他のすべてのフィールドはデフォルトのままにしてください。
フィールド | 値 |
---|---|
クライアント名 | Demo OIDC Client |
クライアントの詳細情報 | Example client for OIDC tutorial |
クライアントタイプ | 機密 |
クライアントを作成したら、クライアント設定 > エンドポイント > 基本設定に移動します。リダイレクト URI セクションで [追加] をクリックし、クライアントが認可レスポンスを受け取る URI を入力して保存します。
以下はクライアントを作成したときに生成または指定されたプロパティの例です。これらの値は、認可コードフローの一環としてリクエストを行う際に必要となります。環境設定セクションで記録した値を使用してください。
項目 | 値 |
---|---|
サービス ID | 自動生成 (例: 10738933707579 ) |
サービスアクセストークン | 自動生成 (例: Xg6jVpJCvsaXvy2ks8R5WzjdMYlvQqOym3slDX0wNhQ ) |
クライアント ID | 自動生成 (例: 12898884596863 ) |
クライアントシークレット | 自動生成 (例: -olDIKD9BihRfB8O1JxobUEKBZ7PIV5Z6oaqxAshmoUtUZgB-wjmmxTYDiDV6vM_Mgl267PeNrRftq8cWplvmg ) |
クライアントタイプ | 機密 |
リダイレクト URI | https://client.example.org/cb/example.com |
クライアント認証方式 | CLIENT_SECRET_BASIC |
これで、この環境を使用して OIDC 認可コードフローを試す準備が整いました。
以下のシーケンス図を提供して、コードフローに関与する各ステップを理解できるようにしています。このウォークスルー内の位置を確認するため、対応する番号を使用してステップを識別できます。
以下の値を例としてリクエストのパラメータに使用します (前述の通り)。
項目 | 値 | 説明 |
---|---|---|
client_id | 12898884596863 |
登録済みクライアント ID |
response_type | code |
OIDC 認可コードフローを示す値 (scope に openid を含む場合) |
redirect_uri | https://client.example.org/cb/example.com |
登録済みリダイレクト URI の一つ |
scope | openid |
OIDC 認証リクエストであることを示す値 |
nonce | n-0S6_WzA2Mj |
ノンス値 (3.1.2.1. 認証リクエスト - OpenID Connect Core 1.0 を参照) |
リソースオーナーがクライアントを介して保護されたリソースにアクセスしようとすると (ステップ #1、#2)、クライアントはユーザーエージェントを介して認可リクエスト (OIDC 認証リクエスト) を認可サーバーに送信します (ステップ #3、#4)。
認可サーバーは、以下に示すように、ユーザーエージェントから HTTP GET
クエリ文字列としてデータを受け取ります。
redirect_uri=https://client.example.org/cb/example.com
&response_type=code
&client_id=12898884596863
&scope=openid
&nonce=n-0S6_WzA2Mj
認可サーバーの役割は、これらのパラメータを評価することです。以下は典型的な評価ルールです:
12898884596863
に関連付けられたクライアントが認可サーバーに登録されているかどうか。scope=openid
の場合、このクライアントは OIDC リライングパーティである必要があります。https://client.example.org/cb/example.com
の値が、クライアントに登録された URI の一つと一致しているかどうか。response_type
や scope
などの他のパラメータの値が、クライアントに対して許可されているかどうか。その後、scope
と response_type
の値がそれぞれ openid
と code
であるため、認可サーバーは OIDC 認可コードフローを処理します。
ただし、Authlete アーキテクチャでは、認可サーバーは単に Authlete API によって処理される認可ロジックのプロキシとして機能します。このロジックは /auth/authorization
エンドポイントで公開されています。リクエストを受け取ると、Authlete API が認可サーバーに代わって評価プロセスを実行します。
ここから、認可サーバーのリクエストをこの API にシミュレートします。
以下のように curl
コマンドを実行してください (メッセージ #5)。前のステップで生成した <サービス ID>
(Service ID
)、<サービス アクセス トークン>
(Service Access Token
)、および <クライアント ID>
(Client ID
) を置き換えて使用します。
curl -s -X POST https://us.authlete.com/api/<Service ID e.g. 10738933707579>/auth/authorization \
-H 'Authorization: Bearer <Service Access Token e.g. Xg6jVpJCvsaXvy2ks8R5WzjdMYlvQqOym3slDX0wNhQ>' \
-H 'Content-Type: application/json' \
-d '{ "parameters": "redirect_uri=https://client.example.org/cb/example.com&response_type=code&client_id=<Client ID e.g. 12898884596863>&scope=openid&nonce=n-0S6_WzA2Mj" }'
成功すると、Authlete は次のようなレスポンスを返します (簡略化のため省略されています) (メッセージ #6)。
{
"resultMessage" : "[A004001] Authlete has successfully issued a ticket to the service (API Key = 10738933707579) for the authorization request from the client (ID = 12898884596863). [response_type=code, openid=true]",
"resultCode" : "A004001",
"client" : { [...] },
"ticket" : "bi2Kxe2WW5mK_GZ_fDFOpK1bnY6xTy40Ap_8nxf-7AU",
"action" : "INTERACTION",
[...]
"service" : {
[...]
"supportedClaims" : null,
"supportedScopes" : null,
}
}
このレスポンスの resultMessage
、action
、ticket
の 3 つのキー/値ペアに注意してください。
resultMessage
: リクエスト処理の結果を人間が読める形式で提供します。openid=true
は、リクエストが OIDC プロトコルに従って処理されることを示します。action
: 認可サーバーが次に行うべきアクションを示します。ticket
: 次のステップで別の API にリクエストを行うために必要です。Authlete はまた、レスポンス内にサービスおよびクライアント情報を提供します。認可サーバーはこれを使用して、リソースオーナーがクライアントに対してアクセスを許可するかどうかを尋ねます。
リソースオーナーと認可サーバー間の実際のやり取りは、このチュートリアルの範囲外です。通常、認可サーバーは以下のプロセスを実行します:
これらのプロセスは、ステップ #7、#8、#9 に対応します。
次に進む前に、認可サーバーが以下の状態にあると仮定します:
subject
パラメータとして Authlete に共有されるリソースオーナーの識別子が testuser01
であることを決定した。認可サーバーは、Authlete の /auth/authorization/issue
にリクエストを送信し、認可コードを発行します。このリクエストには、subject
と /auth/authorization
API のレスポンスに含まれる ticket
の値が含まれます。
以下の curl
コマンドを実行してください (メッセージ #10)。先ほど生成した <Service ID>
、<Service Access Token>
、および <Ticket>
を置き換えて使用します。
curl -s -X POST https://us.authlete.com/api/<Service ID e.g. 10738933707579>/auth/authorization/issue \
-H 'Authorization: Bearer <Service Access Token e.g. Xg6jVpJCvsaXvy2ks8R5WzjdMYlvQqOym3slDX0wNhQ>' \
-H 'Content-Type: application/json' \
-d '{ "ticket": "<Ticket e.g. bi2Kxe2WW5mK_GZ_fDFOpK1bnY6xTy40Ap_8nxf-7AU>", "subject": "testuser01" }'
成功すると、Authlete は次のようなレスポンスを返します (ステップ #11)。
{
"action" : "LOCATION",
"resultCode" : "A040001",
"accessTokenDuration" : 0,
"accessTokenExpiresAt" : 0,
"resultMessage" : "[A040001] The authorization request was processed successfully.",
"responseContent" : "https://client.example.org/cb/example.com?code=GrYz5vtk6VaF0jxfnDrB2yvmk4deIrnMkrGT07JdM5U",
"authorizationCode" : "GrYz5vtk6VaF0jxfnDrB2yvmk4deIrnMkrGT07JdM5U",
...
}
このレスポンスの resultMessage
、action
、responseContent
の 3 つのキー/値ペアに注目してください。
resultMessage
: リクエスト処理の結果を人間が読める形式で提供します。action
: 認可サーバーが次に行うべきアクションを示します。このレスポンスの値は LOCATION
であり、認可サーバーがユーザーエージェントにリダイレクトレスポンスを返すべきことを示しています。responseContent
: 認可サーバーからのレスポンス内容を示します。認可サーバーは、以下のようなレスポンスをユーザーエージェントに送信します (ステップ #12)。
HTTP/1.1 302 Found
Location: https://client.example.org/cb/example.com
?code=GrYz5vtk6VaF0jxfnDrB2yvmk4deIrnMkrGT07JdM5U
場合によっては、認可サーバーがリソースオーナーから認可を受けられないことがあります。この場合、クライアントにトークンを発行せず、認可フローが終了したことを通知する必要があります。Authlete の /auth/authorization/fail
API は、クライアントに送信されるメッセージおよびレスポンスの転送方法の観点から、この終了プロセスをサポートします。
まとめると、通常の状況では、認可サーバーはユーザー認証と同意の結果に応じて、/auth/authorization/issue
または /auth/authorization/fail
API のいずれかにリクエストを送信します。
ここでは、ユーザーエージェントが認可サーバーからのリダイレクトレスポンスを受け取ったと仮定します。このリダイレクトレスポンスは以下のようにクライアントに転送されます (ステップ #13)。
GET /cb/example.com?code=GrYz5vtk6VaF0jxfnDrB2yvmk4deIrnMkrGT07JdM5U 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(12898884596863:-olDIKD9BihRfB8O1JxobUEKBZ7PIV5Z6oaqxAshmoUtUZgB-wjmmxTYDiDV6vM_Mgl267PeNrRftq8cWplvmg)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=GrYz5vtk6VaF0jxfnDrB2yvmk4deIrnMkrGT07JdM5U
&redirect_uri=https://client.example.org/cb/example.com
認可サーバーは、リクエストのパラメータを評価し、クライアントにトークンレスポンスを返すために Authlete API にリクエストを送信します。
ここで、このステップをシミュレートするために Authlete の /auth/token
API を使用します。この API はリクエストを評価し、レスポンスを生成します。
以下の curl
コマンドを実行してください (ステップ #15)。先ほど生成した <Service ID>
、<Service Access Token>
、<Client ID>
、<Client Secret>
、および <Code>
を置き換えて使用します。
curl -s -X POST https://us.authlete.com/api/<Service ID e.g. 10738933707579>/auth/token \
-H 'Authorization: Bearer <Service Access Token e.g. Xg6jVpJCvsaXvy2ks8R5WzjdMYlvQqOym3slDX0wNhQ>' \
-H 'Content-Type: application/json' \
-d '{ "clientId": "<Client ID e.g. 12898884596863>", "clientSecret": "<Client Secret e.g. -olDIKD9BihRfB8O1JxobUEKBZ7PIV5Z6oaqxAshmoUtUZgB-wjmmxTYDiDV6vM_Mgl267PeNrRftq8cWplvmg>", "parameters": "grant_type=authorization_code&code=<Code e.g. GrYz5vtk6VaF0jxfnDrB2yvmk4deIrnMkrGT07JdM5U>&redirect_uri=https://client.example.org/cb/example.com" }'
成功すると、Authlete は次のようなレスポンスを返します (メッセージ #16)。
{
"resultMessage" : "[A050001] The token request (grant_type=authorization_code) was processed successfully.",
"action" : "OK",
"clientIdAliasUsed" : false,
"subject" : "testuser01",
"resultCode" : "A050001",
"refreshTokenExpiresAt" : 1730552811449,
"grantType" : "AUTHORIZATION_CODE",
"accessToken" : "7FfwOnGjVHwxXhs2Wr67XV1-ZhQaoy3ctKcGkLyKxuY",
"idToken" : "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjEyODk4ODg0NTk2ODYzIl0sImlzcyI6Imh0dHBzOi8vYXV0aGxldGUuY29tIiwiZXhwIjoxNTU5MTA2ODE1LCJpYXQiOjE1NTkwMjA0MTUsIm5vbmNlIjoibi0wUzZfV3pBMk1qIn0.5uSFMTGnubyvtiExHc9l7HT9UsF8a_Qb0STtWzyclBk",
"responseContent" : "{\"access_token\":\"7FfwOnGjVHwxXhs2Wr67XV1-ZhQaoy3ctKcGkLyKxuY\",\"refresh_token\":\"T1h7fJ6k55CyipDtXNPbzN8ta3FgAAf4QKjo36OVfIE\",\"scope\":\"openid\",\"id_token\":\"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjEyODk4ODg0NTk2ODYzIl0sImlzcyI6Imh0dHBzOi8vYXV0aGxldGUuY29tIiwiZXhwIjoxNTU5MTA2ODE1LCJpYXQiOjE1NTkwMjA0MTUsIm5vbmNlIjoibi0wUzZfV3pBMk1qIn0.5uSFMTGnubyvtiExHc9l7HT9UsF8a_Qb0STtWzyclBk\",\"token_type\":\"Bearer\",\"expires_in\":86400}",
"scopes" : [
"openid"
],
"accessTokenDuration" : 86400,
"type" : "tokenResponse",
"refreshToken" : "T1h7fJ6k55CyipDtXNPbzN8ta3FgAAf4QKjo36OVfIE",
"accessTokenExpiresAt" : 1730552811449,
"refreshTokenDuration" : 864000,
"clientId" : 12898884596863
}
このレスポンスの resultMessage
、action
、responseContent
の 3 つのキー/値ペアに注目してください。
resultMessage
: リクエスト処理の結果を人間が読める形式で提供します。action
: 認可サーバーが次に行うべきアクションを示します。この場合の値は OK
であり、認可サーバーがクライアントにトークンレスポンスを返すべきことを示しています。responseContent
: 認可サーバーからクライアントへのレスポンス内容を示します。認可サーバーは以下のレスポンスをクライアントに送信する必要があります (メッセージ #17)。
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token":"7FfwOnGjVHwxXhs2Wr67XV1-ZhQaoy3ctKcGkLyKxuY",
"refresh_token":"T1h7fJ6k55CyipDtXNPbzN8ta3FgAAf4QKjo36OVfIE",
"scope":"openid",
"id_token":"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjEyODk4ODg0NTk2ODYzIl0sImlzcyI6Imh0dHBzOi8vYXV0aGxldGUuY29tIiwiZXhwIjoxNTU5MTA2ODE1LCJpYXQiOjE1NTkwMjA0MTUsIm5vbmNlIjoibi0wUzZfV3pBMk1qIn0.5uSFMTGnubyvtiExHc9l7HT9UsF8a_Qb0STtWzyclBk",
"token_type":"Bearer",
"expires_in":86400
}
クライアントはこのレスポンスを受信すると、必要に応じて ID トークンをデコードします。
クライアントは、レスポンス内の id_token
の値をデコードし、その有効性を確認する必要があります。
このチュートリアルでは、無料のオープンソースツール Online JWT Verifier を使用してトークンをデコードします。
以下のリンクを開き、JWT Verifier UI の (Step 1) Set JWT (JSON Web Token) to verify テキストエリアに id_token
の値を貼り付けてください。このチュートリアルの例では ID
トークンの値として eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjEyODk4ODg0NTk2ODYzIl0sImlzcyI6Imh0dHBzOi8vYXV0aGxldGUuY29tIiwiZXhwIjoxNTU5MTA2ODE1LCJpYXQiOjE1NTkwMjA0MTUsIm5vbmNlIjoibi0wUzZfV3pBMk1qIn0.5uSFMTGnubyvtiExHc9l7HT9UsF8a_Qb0STtWzyclBk
を使用します。
その後、(Step 3) Verify セクション内の Just Decode JWT ボタンをクリックして、Parsed JWT セクションにデコードされた内容を確認してください。
デコード結果は以下のようになります。
ヘッダー:
{
"alg": "HS256"
}
ペイロード:
{
"sub": "testuser01",
"aud": [
"12898884596863"
],
"iss": "https://authlete.com",
"exp": 1730552811,
"iat": 1730552811,
"nonce": "n-0S6_WzA2Mj"
}
上記の内容には、修正が必要な点がいくつかあります。
iss
が https://authlete.com
となっていますが、これは Authlete のデフォルト値です。このチュートリアルでは、認可サーバーの識別子として https://as.example.com
にする必要があります。sub
はユーザーの識別に関する唯一の属性です。クライアントの利便性のために、他のユーザー属性を追加することが望ましいです。次のセクションでは、iss
の値を修正し、追加のクレームを追加します。
https://console.authlete.com にログインし、このチュートリアルで作成した Demo AS サービスを選択します。サービス設定 ボタンをクリックして、サービス設定にアクセスします。
一般 タブにある 発行者識別子 のデフォルト値が https://authlete.com
であることに注意してください。この値を https://as.example.com
に変更し、ページ下部の 変更を保存 ボタンをクリックして保存します。
確認ダイアログが表示されたら OK をクリックします。
これで、ID トークンの発行者識別子 iss
が修正されました。
先ほどと同じ認可リクエストを送信します (便宜上、同じ nonce
値を使用します)。このリクエストは Authlete の /auth/authorization
API に送信されます (ステップ #5)。以下のように <Service ID>
、<Service Access Token>
、および <Client ID>
を置き換えて使用してください。
curl -s -X POST https://us.authlete.com/api/<Service ID e.g. 10738933707579>/auth/authorization \
-H 'Authorization: Bearer <Service Access Token e.g. Xg6jVpJCvsaXvy2ks8R5WzjdMYlvQqOym3slDX0wNhQ>' \
-H 'Content-Type: application/json' \
-d '{ "parameters": "redirect_uri=https://client.example.org/cb/example.com&response_type=code&client_id=<Client ID e.g. 12898884596863>&scope=openid&nonce=n-0S6_WzA2Mj" }'
以下のようなレスポンスを受け取るはずです (簡略化のため省略されています)。
{
[...]
"action" : "INTERACTION",
"resultCode" : "A004001",
"resultMessage" : "[A004001] Authlete has successfully issued a ticket to the service (API Key = 10738933707579) for the authorization request from the client (ID = 12898884596863). [response_type=code, openid=true]",
"ticket" : "JjQ_Th1UvZyU5MsdKTLIfLv3VlKwEiYnnULmW6l_d9A",
}
次に、認可コードを発行するために Authlete の /auth/authorization/issue
API にリクエストを送信します。このリクエストに含まれるクレームには以下の追加項目を含めます。
項目 | 値 |
---|---|
name |
Test User |
email |
testuser01@example.com |
email_verified |
true |
以下の claims
パラメータを使用してクレームを追加します。リクエストは以下のように構築されます。
curl -s -X POST https://us.authlete.com/api/<Service ID e.g. 10738933707579>/auth/authorization/issue \
-H 'Authorization: Bearer <Service Access Token e.g. Xg6jVpJCvsaXvy2ks8R5WzjdMYlvQqOym3slDX0wNhQ>' \
-H 'Content-Type: application/json' \
-d '{ "ticket": "<Ticket e.g. JjQ_Th1UvZyU5MsdKTLIfLv3VlKwEiYnnULmW6l_d9A>", "subject": "testuser01", "claims": "{\"name\": \"Test User\", \"email\": \"testuser01@example.com\", \"email_verified\": true}" }'
以下のようなレスポンスを受け取るはずです。
{
"responseContent" : "https://client.example.org/cb/example.com?code=ILePyGjraVgeU_fzaQRfd0gv10pzxgcpHY_vHT2dsPI",
"accessTokenDuration" : 0,
"authorizationCode" : "ILePyGjraVgeU_fzaQRfd0gv10pzxgcpHY_vHT2dsPI",
"accessTokenExpiresAt" : 0,
"type" : "authorizationIssueResponse",
"resultMessage" : "[A040001] The authorization request was processed successfully.",
"resultCode" : "A040001",
"action" : "LOCATION"
}
認可サーバーは以下のリダイレクトレスポンスをユーザーエージェントに送信する必要があります。その後、ユーザーエージェントは以下のような HTTP GET
リクエストをクライアントに送信します。
GET /cb/example.com?code=ILePyGjraVgeU_fzaQRfd0gv10pzxgcpHY_vHT2dsPI HTTP/1.1
Host: client.example.org
クライアントは以下のようにトークンリクエストを認可サーバーに送信します (改行は可読性向上のため追加されています)。
POST /token HTTP/1.1
Host: as.example.com
Authorization: Basic base64(12898884596863:-olDIKD9BihRfB8O1JxobUEKBZ7PIV5Z6oaqxAshmoUtUZgB-wjmmxTYDiDV6vM_Mgl267PeNrRftq8cWplvmg)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=ILePyGjraVgeU_fzaQRfd0gv10pzxgcpHY_vHT2dsPI
&redirect_uri=https://client.example.org/cb/example.com
認可サーバーは、Authlete の /auth/token
API を呼び出します。
curl -s -X POST https://us.authlete.com/api/<Service ID e.g. 10738933707579>/auth/token \
-H 'Authorization: Bearer <Service Access Token e.g. Xg6jVpJCvsaXvy2ks8R5WzjdMYlvQqOym3slDX0wNhQ>' \
-H 'Content-Type: application/json' \
-d '{ "clientId": "<Client ID e.g. 12898884596863>", "clientSecret": "<Client Secret e.g. -olDIKD9BihRfB8O1JxobUEKBZ7PIV5Z6oaqxAshmoUtUZgB-wjmmxTYDiDV6vM_Mgl267PeNrRftq8cWplvmg>", "parameters": "grant_type=authorization_code&code=<Code e.g. ILePyGjraVgeU_fzaQRfd0gv10pzxgcpHY_vHT2dsPI>&redirect_uri=https://client.example.org/cb/example.com" }'
Authlete は以下のようなレスポンスを返します。
{
"grantType" : "AUTHORIZATION_CODE",
"responseContent" : "{\"access_token\":\"R4sd3s02Y1Gj72iI5Md6ZkGapXZ6mSnIEdihTvrM_Ro\",\"refresh_token\":\"k4WqWw2tcDOHxXXo29NxOCwQJyeDOtZ6aw_Y9Ugy-6U\",\"scope\":\"openid\",\"id_token\":\"eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiVGVzdCBVc2VyIiwiZW1haWwiOiJ0ZXN0dXNlcjAxQGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLCJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjEyODk4ODg0NTk2ODYzIl0sImV4cCI6MTU1OTEzNzMwMSwiaWF0IjoxNTU5MDUwOTAxLCJub25jZSI6Im4tMFM2X1d6QTJNaiJ9.8ngbBoGLUvHXIO4VyGN0-txJfE5Yq86xElMSxqGlLv0\",\"token_type\":\"Bearer\",\"expires_in\":86400}",
"resultMessage" : "[A050001] The token request (grant_type=authorization_code) was processed successfully.",
"accessTokenExpiresAt" : 1730554257440,
"accessToken" : "R4sd3s02Y1Gj72iI5Md6ZkGapXZ6mSnIEdihTvrM_Ro",
"resultCode" : "A050001",
"scopes" : [
"openid"
],
"refreshTokenExpiresAt" : 1730554257440,
"subject" : "testuser01",
"action" : "OK",
"refreshTokenDuration" : 864000,
"accessTokenDuration" : 86400,
"refreshToken" : "k4WqWw2tcDOHxXXo29NxOCwQJyeDOtZ6aw_Y9Ugy-6U",
"clientIdAliasUsed" : false,
"idToken" : "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiVGVzdCBVc2VyIiwiZW1haWwiOiJ0ZXN0dXNlcjAxQGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLCJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjEyODk4ODg0NTk2ODYzIl0sImV4cCI6MTU1OTEzNzMwMSwiaWF0IjoxNTU5MDUwOTAxLCJub25jZSI6Im4tMFM2X1d6QTJNaiJ9.8ngbBoGLUvHXIO4VyGN0-txJfE5Yq86xElMSxqGlLv0",
"clientId" : 12898884596863
}
認可サーバーは以下のレスポンスをクライアントに返すことが期待されます (メッセージ #17)。
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token":"R4sd3s02Y1Gj72iI5Md6ZkGapXZ6mSnIEdihTvrM_Ro",
"refresh_token":"k4WqWw2tcDOHxXXo29NxOCwQJyeDOtZ6aw_Y9Ugy-6U",
"scope":"openid",
"id_token":"eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiVGVzdCBVc2VyIiwiZW1haWwiOiJ0ZXN0dXNlcjAxQGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLCJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjEyODk4ODg0NTk2ODYzIl0sImV4cCI6MTU1OTEzNzMwMSwiaWF0IjoxNTU5MDUwOTAxLCJub25jZSI6Im4tMFM2X1d6QTJNaiJ9.8ngbBoGLUvHXIO4VyGN0-txJfE5Yq86xElMSxqGlLv0",
"token_type":"Bearer",
"expires_in":86400
}
クライアントがこのレスポンスを受信した後、再び Online JWT Verifier を使用してトークンをデコードしてみましょう。
上記リンクを開き、レスポンス内の id_token
の値を Step 1 のテキストエリアに貼り付けます。このチュートリアルでは ID トークンの値として eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiVGVzdCBVc2VyIiwiZW1haWwiOiJ0ZXN0dXNlcjAxQGV4YW1wbGUuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImlzcyI6Imh0dHBzOi8vYXMuZXhhbXBsZS5jb20iLCJzdWIiOiJ0ZXN0dXNlcjAxIiwiYXVkIjpbIjEyODk4ODg0NTk2ODYzIl0sImV4cCI6MTU1OTEzNzMwMSwiaWF0IjoxNTU5MDUwOTAxLCJub25jZSI6Im4tMFM2X1d6QTJNaiJ9.8ngbBoGLUvHXIO4VyGN0-txJfE5Yq86xElMSxqGlLv0
を使用します。
その後、Step 3 の Just Decode JWT ボタンをクリックし、Parsed JWT セクションでデコードされた内容を確認してください。
デコード結果は以下の通りです。
ヘッダー:
{
"alg": "HS256"
}
ペイロード:
{
"name": "Test User",
"email": "testuser01@example.com",
"email_verified": true,
"iss": "https://as.example.com",
"sub": "testuser01",
"aud": [
"12898884596863"
],
"exp": 1559137301,
"iat": 1559050901,
"nonce": "n-0S6_WzA2Mj"
}
これにより、以下の点が確認できます。
iss
の値が正しく設定されています。name
、email
、および email_verified
といった追加クレームが含まれています。このチュートリアルでは、Authlete API を使用して OpenID Connect プロバイダーとして動作する認可サーバーをシミュレートし、認可コードフローを用いて ID トークンを発行する方法を学びました。以下の重要なステップを完了しました。
このウォークスルーでは一部のプロセスを簡略化しましたが、Authlete をバックエンドサービスとして利用することで、独自のインフラストラクチャ上でホストされる認可サーバーがどのように動作するかを深く理解できたはずです。独自の認可サーバーを構築する場合、複雑なロジックやコード、シークレットの安全な取り扱いに細心の注意を払う必要がありますが、Authlete API を利用することで、これらの実装を大幅に簡素化できます。
以下の機能を試し、Authlete をさらに深く理解しましょう。
/auth/authorization/fail
API (参考: “fail” API を用いたエラーレスポンスの生成)/auth/userinfo
API (参照: Access token verification in Userinfo API)