Table of Contents
このドキュメントでは、OAuth 2.0 の Authorization Code Grant Flow に対応した認可サーバーを構築する際の、Authlete API の基本的な利用方法について説明します。
本チュートリアルでは以下の構成を想定します。 なお、実サービスとして動作するのは、Authlete のコンソールと API だけです。
認可サーバーとリソースサーバーはいずれも実際には存在しませんが、 それぞれのサーバーがクライアントから認可リクエストやトークンリクエスト、そしてトークンイントロスペクションリクエストを受信したときに、 どのような API リクエストを Authlete に行うかを、curl コマンドを用いて試行します。
各サービスの FQDN は以下の通りです。上述の通り認可サーバーとクライアントは存在しませんが、OAuth のフローを説明する上で FQDN が最低限必要となります。
サービス | FQDN |
---|---|
Authlete API | api.authlete.com |
Authlete サービス管理者コンソール (Service Owner Console) | so.authlete.com |
Authlete クライアントアプリ開発者コンソール (Developer Console) | cd.authlete.com |
認可サーバー (Authorization Server) | as.example.com |
クライアント (Client) | client.example.org |
リソースサーバー (Resource Server) | N/A |
チュートリアル「サインアップから Authlete サービス作成までの手順」に従い、 新規 Authlete API サービスの作成と、そのサービスへのクライアント登録を行います。
本チュートリアルでは、環境設定の結果として以下の値を生成・指定したものとします。
項目 | 値 |
---|---|
クライアント ID | 自動生成された値(例: 12800697055611 ) |
クライアントシークレット | 自動生成された値(例: dcDHEXr_tXNi7QdIMXLSXpXAy_j7Cr4C4LT2xAukQcW_09E2Ag1jTBdwpQrG-HBxflPF4Bz_Nb9Zd_ySAxOs6A ) |
クライアントタイプ | CONFIDENTIAL |
リダイレクト URI | https://client.example.org/cb/example.com |
クライアント認証方式 | CLIENT_SECRET_BASIC |
この構成を用いて、認可サーバーとクライアントからなる、認可コードグラントフローを試してみましょう。
シーケンス図を以下に示します。以降の説明においては、この図にあるメッセージ番号を併せてご参照ください。
クライアントはユーザーエージェントを経由して、認可サーバーに認可リクエストを送信します(メッセージ番号 2, 3)。 ここでは認可リクエストのパラメーターとして以下が指定されていたものとします。
項目 | 値 |
---|---|
client_id | 12800697055611 |
response_type | code |
redirect_uri | https://client.example.org/cb/example.com |
認可サーバーは、ユーザーエージェントからのリクエストのクエリストリングとして、以下の内容(一部折り返しています)を受信することになります(メッセージ番号 3)。
redirect_uri=https://client.example.org/cb/example.com
&response_type=code
&client_id=12800697055611
認可サーバーは、本来はこれらのパラメーターの検証を自ら行う必要があります。
以下の検証後に認可サーバーは、response_type
の値が code
であることから、今回は認可コードグラントフローとして処理することになります。
110723797812772
に相当するクライアントが、認可サーバーに登録されているかどうかhttps://client.example.org/cb/example.com
が、そのクライアントに事前登録されているリダイレクト URI のどれかに合致するかこの検証プロセスを代行するのが Authlete の /auth/authorization
API です。
認可サーバーの立場になり、この API にリクエストしてみましょう。
curl コマンドを以下のように実行します(メッセージ番号 4)。なお、API Key
, API Secret
, Client ID
は、本チュートリアルの過程にて生成された値に置き換えてください。
curl -s -X POST https://api.authlete.com/api/auth/authorization \
-u '<API Key e.g. 10723797812772>:<API Secret e.g. ekYoYTI84qZcpe6bXGzDwduQ1fGBYxJT8K8Tnwd7poc>' \
-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. 12800697055611>" }'
Windows 10 の PowerShell から curl.exe コマンドを用いる場合には、以下のようになります。curl
ではなく curl.exe
とすること、"
をエスケープすること、行の区切りに `
を用いることにご注意ください。(メッセージ番号 4)。
なお、API Key
, API Secret
, Client ID
は、本チュートリアルの過程にて生成された値に置き換えてください。
curl.exe -s -X POST https://api.authlete.com/api/auth/authorization `
-u '<API Key e.g. 10723797812772>:<API Secret e.g. ekYoYTI84qZcpe6bXGzDwduQ1fGBYxJT8K8Tnwd7poc>' `
-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. 12800697055611>\"}'
リクエストが適切な場合、Authlete から以下のようなレスポンス(見やすさのため改行し一部省略)が返却されます(メッセージ番号 5)。
{
"resultMessage" : "[A004001] Authlete has successfully issued a ticket to the service (API Key = 10723797812772) for the authorization request from the client (ID = 12800697055611). [response_type=code, openid=false]",
"type" : "authorizationResponse",
"resultCode" : "A004001",
"client" : { [...] },
"ticket" : "bi2Kxe2WW5mK_GZ_fDFOpK1bnY6xTy40Ap_8nxf-7AU",
"action" : "INTERACTION",
[...]
"service" : {
[...]
"supportedClaims" : [
[...]
],
"supportedScopes" : [
[...]
],
}
}
このうち、とくに注目すべきキーは、 resultMessage
, action
, ticket
です。
{
[...]
"ticket" : "bi2Kxe2WW5mK_GZ_fDFOpK1bnY6xTy40Ap_8nxf-7AU",
"action" : "INTERACTION",
"resultMessage" : "[A004001] Authlete has successfully issued a ticket to the service (API Key = 10723797812772) for the authorization request from the client (ID = 12800697055611). [response_type=code, openid=false]",
resultMessage
: リクエストの処理結果をわかりやすく示しています。(参考: Authlete の result code について)action
: 認可サーバーが次に何をすべきかを示します。ticket
: 認可フロー処理の次のステップにて、後述する別の Authlete API を呼ぶときに必要な値となります。それ以外に返却される値として、サービス情報とクライアント情報があります。認可サーバーはこれらの値を用いて、ユーザーに、「どのようなサービスに対する、どのようなアクセス権限を、どのようなクライアントに許可するか」を確認することになります。
このチュートリアルの中では、ユーザーと具体的にどのようなインタラクションを行うかについては言及しません。多くの場合、認可サーバーはユーザーを何らかの方法(ID/パスワードなど)を用いて認証し、ユーザーのロールや権限を確認したのちに、前述したアクセス権限付与の確認を行います(メッセージ番号 6, 7)。
ユーザー認証とアクセス権限付与確認が完了することにより、認可サーバーは以下の状態に至ったとします。
subject
)として testuser01
を用いる。認可サーバーはこれをうけて、Authlete の /auth/authorization/issue
API を用いて、認可コードの発行を指示します。
認可サーバーは subject
と、先ほど /auth/authorization
API のレスポンスから取得した ticket
の値を、 この API へのリクエストのパラメーターとして指定します。
curl コマンドを以下のように実行します(メッセージ番号 8)。なお、API Key
, API Secret
, Ticket
は、本チュートリアルの過程にて生成された値に置き換えてください。
curl -s -X POST https://api.authlete.com/api/auth/authorization/issue \
-u '<API Key e.g. 10723797812772>:<API Secret e.g. ekYoYTI84qZcpe6bXGzDwduQ1fGBYxJT8K8Tnwd7poc>' \
-H 'Content-Type: application/json' \
-d '{ "ticket": "<Ticket e.g. bi2Kxe2WW5mK_GZ_fDFOpK1bnY6xTy40Ap_8nxf-7AU>", "subject": "testuser01" }'
curl.exe コマンドを以下のように実行します(メッセージ番号 8)。なお、API Key
, API Secret
, Ticket
は、本チュートリアルの過程にて生成された値に置き換えてください。
curl.exe -s -X POST https://api.authlete.com/api/auth/authorization/issue `
-u '<API Key e.g. 10723797812772>:<API Secret e.g. ekYoYTI84qZcpe6bXGzDwduQ1fGBYxJT8K8Tnwd7poc>' `
-H 'Content-Type: application/json' `
-d '{ \"ticket\": \"<Ticket e.g. bi2Kxe2WW5mK_GZ_fDFOpK1bnY6xTy40Ap_8nxf-7AU>\", \"subject\": \"testuser01\" }'
リクエストが適切な場合、Authlete から以下のようなレスポンス(見やすさのため改行)が返却されます(メッセージ番号 9)。
{
"action" : "LOCATION",
"resultCode" : "A040001",
"type" : "authorizationIssueResponse",
"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
, です。
resultMessage
, action
: 先の /auth/authorization
API と同様に、リクエストの処理結果と、認可サーバーが次に何をすべきかを示します。今回は action
の値として LOCATION
が指定されています。これは、認可サーバーはクライアントにリダイレクトレスポンスを返却してくださいという意味です。responseContent
: レスポンスの内容として指定する値です。結果的に、認可サーバーは、以下のレスポンス(一部折り返しています)をユーザーエージェントに返却することが期待されます(メッセージ番号 10)。
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
を使い分けることになります。
先のレスポンスを認可サーバーがユーザーエージェントに返却した結果、ユーザーエージェントは以下のリクエスト(一部折り返しています)をクライアントに送信することになります(メッセージ番号 11)。
GET /cb/example.com?code=GrYz5vtk6VaF0jxfnDrB2yvmk4deIrnMkrGT07JdM5U HTTP/1.1
Host: client.example.org
クライアントはこのリクエストから code
の値を抽出し、トークンリクエストを組み立て、認可サーバーに送信します(一部折り返しています)。
ここではトークンエンドポイントを https://as.example.com/token
とします(メッセージ番号 12)。
POST /token HTTP/1.1
Host: as.example.com
Authorization: Basic base64(12800697055611:dcDHEXr_tXNi7QdIMXLSXpXAy_j7Cr4C4LT2xAukQcW_09E2Ag1jTBdwpQrG-HBxflPF4Bz_Nb9Zd_ySAxOs6A)
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=GrYz5vtk6VaF0jxfnDrB2yvmk4deIrnMkrGT07JdM5U
&redirect_uri=https://client.example.org/cb/example.com
このトークンリクエストを受け取った認可サーバーは、先の認可リクエスト処理のときと同様に、パラメーターの検証を行い、トークンレスポンスをクライアントに返却することになります。
本チュートリアルでは、この一連の処理を Authlete の /auth/token
API を用いて行います。
curl コマンドを以下のように実行します(メッセージ番号 13)。なお、API Key
, API Secret
, Client ID
, Client Secret
, Code
は、本チュートリアルの過程にて生成された値に置き換えてください。
curl -s -X POST https://api.authlete.com/api/auth/token \
-u '<API Key e.g. 10723797812772>:<API Secret e.g. ekYoYTI84qZcpe6bXGzDwduQ1fGBYxJT8K8Tnwd7poc>' \
-H 'Content-Type: application/json' \
-d '{ "clientId": "<Client ID e.g. 12800697055611>", "clientSecret": "<Client Secret e.g. dcDHEXr_tXNi7QdIMXLSXpXAy_j7Cr4C4LT2xAukQcW_09E2Ag1jTBdwpQrG-HBxflPF4Bz_Nb9Zd_ySAxOs6A>", "parameters": "grant_type=authorization_code&code=<Code e.g. GrYz5vtk6VaF0jxfnDrB2yvmk4deIrnMkrGT07JdM5U>&redirect_uri=https://client.example.org/cb/example.com" }'
curl.exe コマンドを以下のように実行します(メッセージ番号 13)。なお、API Key
, API Secret
, Client ID
, Client Secret
, Code
は、本チュートリアルの過程にて生成された値に置き換えてください。
curl.exe -s -X POST https://api.authlete.com/api/auth/token `
-u '<API Key e.g. 10723797812772>:<API Secret e.g. ekYoYTI84qZcpe6bXGzDwduQ1fGBYxJT8K8Tnwd7poc>' `
-H 'Content-Type: application/json' `
-d '{ \"clientId\": \"<Client ID e.g. 12800697055611>\", \"clientSecret\": \"<Client Secret e.g. dcDHEXr_tXNi7QdIMXLSXpXAy_j7Cr4C4LT2xAukQcW_09E2Ag1jTBdwpQrG-HBxflPF4Bz_Nb9Zd_ySAxOs6A>\", \"parameters\": \"grant_type=authorization_code&code=<Code e.g. GrYz5vtk6VaF0jxfnDrB2yvmk4deIrnMkrGT07JdM5U>&redirect_uri=https://client.example.org/cb/example.com\" }'
リクエストが適切な場合、Authlete から以下のようなレスポンス(見やすさのため改行)が返却されます(メッセージ番号 14)。
{
"resultMessage" : "[A050001] The token request (grant_type=authorization_code) was processed successfully.",
"action" : "OK",
"clientIdAliasUsed" : false,
"subject" : "testuser01",
"resultCode" : "A050001",
"refreshTokenExpiresAt" : 1559288344881,
"grantType" : "AUTHORIZATION_CODE",
"accessToken" : "7FfwOnGjVHwxXhs2Wr67XV1-ZhQaoy3ctKcGkLyKxuY",
"responseContent" : "{\"access_token\":\"7FfwOnGjVHwxXhs2Wr67XV1-ZhQaoy3ctKcGkLyKxuY\",\"refresh_token\":\"T1h7fJ6k55CyipDtXNPbzN8ta3FgAAf4QKjo36OVfIE\",\"scope\":null,\"token_type\":\"Bearer\",\"expires_in\":86400}",
"accessTokenDuration" : 86400,
"type" : "tokenResponse",
"refreshToken" : "T1h7fJ6k55CyipDtXNPbzN8ta3FgAAf4QKjo36OVfIE",
"accessTokenExpiresAt" : 1558510744881,
"refreshTokenDuration" : 864000,
"clientId" : 12800697055611
}
このうち、特に注目すべきキーは、resultMessage
, action
, responseContent
です。
resultMessage
, action
: これまでと同様に、リクエストの処理結果と、認可サーバーが次に何をすべきかを示します。今回は action
の値として OK
が指定されています。これは、正常に処理が完了したので認可サーバーはクライアントにレスポンスを返却してくださいという意味です。responseContent
: レスポンスの内容として指定する値です。認可サーバーは、以下のレスポンスをクライアントに返却することが期待されます(メッセージ番号 15)。
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token":"7FfwOnGjVHwxXhs2Wr67XV1-ZhQaoy3ctKcGkLyKxuY",
"refresh_token":"T1h7fJ6k55CyipDtXNPbzN8ta3FgAAf4QKjo36OVfIE",
"scope":null,
"token_type":"Bearer",
"expires_in":86400
}
以上により、認可サーバーはトークンを生成し、クライアントに提供することができました。そして Authlete の API を活用することにより認可サーバーは、複雑な処理を実装せずとも、認可リクエストやトークンリクエストのパラメーターを正しく検証し、さらに正しいレスポンス内容を返却することができました。
このあと実際には、クライアントはリソースサーバーに対して、アクセストークンを含むリクエストを送信し、API の利用を試みることになります(メッセージ番号 16)。
アクセストークンを受け取ったリソースサーバーは、そのトークンの有効性を確認し、さらにトークンに付随するユーザーやクライアントの情報を取得して、どのような結果をクライアントに返却すべきか(すべきではないか)を判断する必要があります。
Authlete には、トークンの有効性を検証しその結果を返却する、/auth/introspection
API が存在します。
curl コマンドを以下のように実行します(メッセージ番号 17)。なお、API Key
, API Secret
, Token
は、本チュートリアルの過程にて生成された値に置き換えてください。
curl -s -X POST https://api.authlete.com/api/auth/introspection \
-u '<API Key e.g. 10723797812772>:<API Secret e.g. ekYoYTI84qZcpe6bXGzDwduQ1fGBYxJT8K8Tnwd7poc>' \
-H 'Content-Type: application/json' \
-d '{ "token": "<Token e.g. 7FfwOnGjVHwxXhs2Wr67XV1-ZhQaoy3ctKcGkLyKxuY>" }'
curl.exe コマンドを以下のように実行します(メッセージ番号 17)。なお、API Key
, API Secret
, Token
は、本チュートリアルの過程にて生成された値に置き換えてください。
curl -s -X POST https://api.authlete.com/api/auth/introspection `
-u '<API Key e.g. 10723797812772>:<API Secret e.g. ekYoYTI84qZcpe6bXGzDwduQ1fGBYxJT8K8Tnwd7poc>' `
-H 'Content-Type: application/json' `
-d '{ \"token\": \"<Token e.g. 7FfwOnGjVHwxXhs2Wr67XV1-ZhQaoy3ctKcGkLyKxuY>\" }'
リクエストが適切な場合、Authlete から以下のようなレスポンス(見やすさのため改行)が返却されます(メッセージ番号 18)。
{
"clientIdAliasUsed" : false,
"type" : "introspectionResponse",
"resultCode" : "A056001",
"responseContent" : "Bearer error=\"invalid_request\"",
"action" : "OK",
"subject" : "testuser01",
"expiresAt" : 1558510744000,
"existent" : true,
"resultMessage" : "[A056001] The access token is valid.",
"refreshable" : true,
"sufficient" : true,
"usable" : true,
"clientId" : 12800697055611
}
リソースサーバーはこのレスポンス結果から、アクセストークンの有効期限 (expiresAt
) や、アクセス認可を行なったユーザーの識別子 (subject
) などを取得します。そしてそれらの値に基づいて、クライアントに対する API レスポンスを決定できるようになります(メッセージ番号 19)。
本チュートリアルでは、認可サーバーに認可コードグラントフローを実装する際の Authlete API の利用方法について、実際の動作を確認しました。
チュートリアルの次のステップとして以下を試し、Authlete への理解を深めましょう。
/auth/authorization/fail
API の利用(参考: “fail” API を用いたエラーレスポンスの生成 )