Table of Contents
Userinfo API が応答するクレームは ID トークンに任意のクレームを追加する方法 と同様に、claims パラメータを利用することでカスタマイズできます。
この記事では Userinfo エンドポイントのレスポンスに任意のクレームを追加する方法と、クレームの決定に役立つ Authlete の機能について解説します。
OpenID プロバイダーが Authlete を利用し Userinfo API エンドポイントを実装する場合、以下の 2 つの API を呼び出す必要があります。
Authlete の Userinfo Request エンドポイントはアクセストークンを提示することにより、アクセストークンの検証をしたうえで、トークンに紐づくユーザーの情報を応答します。 OpenID プロバイダーは Userinfo Request の応答からトークンの有効性と紐づいたユーザーを確認し、対象ユーザーの属性をデータストアから収集し、Issue Userinfo Response API に提示します。
具体的な例は以下の通りです。まず OpenID プロバイダーはユーザーが提示したアクセストークンを Authlete の Userinfo Request API に送信します。
curl --request POST \
--url https://jp.authlete.com/api/{{serviceId}}/auth/userinfo \
--header 'authorization: Bearer {{serviceAccessToken}}' \
--header 'content-type: application/json' \
--data '{"token": "{{accessToken}}"}'
アクセストークンが有効な場合の応答例は以下の通りです。
{
"action": "OK",
"clientId": 2064424232,
"subject": "john",
"scopes": [
"openid",
"email"
],
"claims": [
"email",
"email_verified"
],
"token": "{{accessToken}}",
"clientIdAlias": "2064424232",
"clientIdAliasUsed": true,
"consentedClaims": [
"email",
"email_verified"
],
"clientEntityIdUsed": false,
"resultCode": "A091001",
"resultMessage": "[A091001] The access token presented at the userinfo endpoint is valid."
}
この例では action が OK でトークンが有効であることが示され、さらに subject が john であると判別できるため、 OpenID プロバイダーは john に紐づく属性を収集し、 Issue Userinfo Response に提示します。
Authlete はユーザーに紐づく属性の値は保持しないため、Userinfo エンドポイントの応答に含める属性の値は OpenID プロバイダーが用意する必要があります。一方、OpenID プロバイダーは Userinfo に含める属性を決定するために Authlete が応答する claims パラメータを利用できます。
Userinfo Request API の 応答に含まれる claims パラメータは IDトークンに追加する「クレーム」の判別 と同様に、/auth/authorization エンドポイントに提示された parameters 内の スコープ(scope)に対応するクレーム と、claims パラメーターを用いて個別に指定されるクレームがマージされたリストです。
例えば上記例では scope に openid email が含まれていたため、email スコープが展開され email, email_verified が含めるべきクレームとして claims 応答に含まれます。スコープとそれに対応するクレームの一覧は Authlete Java Common の Javadoc ClaimsScope をご確認ください。
ここでは OpenID プロバイダーが Authlete からの応答 claims に含まれる以下の項目を Userinfo レスポンスに追加する例を示します。
| 項目 | 値 |
|---|---|
| “email” | “john@example.com” |
| “email_verified” | true |
上記のクレームを追加する場合のリクエストは以下のようになります。(読みやすさのため折り返しています。)
curl --request POST \
--url https://jp.authlete.com/api/{{serviceId}}/auth/userinfo/issue \
--header 'authorization: Bearer {{serviceAccessToken}}' \
--header 'content-type: application/json' \
--data '{"token": "{{accessToken}}",
"claims": "{
\"email\": \"john@example.com\",
\"email_verified\": true}"
}'
正常な応答は以下の通りです。responseContent のクレームに指定したクレームが追加されていることが確認できます。
{
"action": "JSON",
"responseContent": "{\"sub\":\"john\",\"email\":\"john@example.com\",\"email_verified\":true}",
"resultCode": "A096001",
"resultMessage": "[A096001] User information was obtained successfully."
}
Authlete が自動で計算する claims は OpenID Connect Core の仕様に則したものですが、実際の運用環境には適さない場合があります。例えば ID トークンに含めるクレームと異なるクレームを Userinfo から返したい、scope は openid, email のみを指定するが OpenID プロバイダーがユーザーの同意内容をもとに追加のクレームを Userinfo エンドポイントから応答したいといった要件があるでしょう。
この場合、Authlete の consentedClaims を利用しユーザーが認可エンドポイントで RP に公開することを許可したクレームを、Introspection エンドポイント や Userinfo エンドポイントに伝達することが可能です。
consentedClaimsは Authlete 2.3 以降で利用できます。consentedClaimsの詳細は Authlete Java Doc AuthorizationIssueRequest.html#setConsentedClaims() を確認ください。
例えばユーザーが認可処理を行った際、氏名とユーザー名、メールアドレスを RP に伝えることに同意し、 OpenID プロバイダーの実装ではそれらの情報を Userinfo エンドポイントから情報を返すような実装を考えます。
認可エンドポイントは以下のようなリクエストを Authlete に送信しチケットを得ます。
curl --request POST \
--url https://jp.authlete.com/api/{{serviceId}}/auth/authorization \
--header 'authorization: Bearer {{serviceAccessToken}}' \
--header 'content-type: application/json' \
--data '{"parameters": "client_id=rest-client-client&scope=openid%20email&response_type=code&redirect_uri=https://example.com&state=xyz&nonce=12345"}'
応答例 (一部省略)
{
"action": "INTERACTION",
"service": {
},
"client": {
},
"display": "PAGE",
"maxAge": 0,
"scopes": [
{
"name": "email",
"defaultEntry": false,
"description": "A permission to request an OpenID Provider to include the email claim and the email_verified claim in an ID Token. See OpenID Connect Core 1.0, 5.4. for details."
},
{
"name": "openid",
"defaultEntry": false,
"description": "A permission to request an OpenID Provider to issue an ID Token. See OpenID Connect Core 1.0, 3.1.2.1. for details."
}
],
"ticket": "IWjy7qiCFJsHYHBKAfwJNLHfoV86lL7KYC0ojmi-Qrk",
"resultCode": "A004001",
"resultMessage": "[A004001] Authlete has successfully issued a ticket to the service (API Key = 666990377) for the authorization request from the client (ID = 1110197986). [response_type=code, openid=true]"
}
OpenID プロバイダーは、氏名とユーザー名、メールアドレスを対象のクライアントに提供するための同意を得たのち、auth/authorization/issue エンドポイントを呼び出します。この際に consentedClaims として name, username, email, email_verified を指定します。
curl --request POST \
--url https://jp.authlete.com/api/{{serviceId}}/auth/authorization \
--header 'authorization: Bearer {{serviceAccessToken}}' \
--header 'content-type: application/json' \
--data '{
"ticket": "{{ticket}}",
"subject": "john",
"claims": "{\"claim_for_id_token\":\"value_for_id_token\"}",
"consentedClaims": ["name", "username", "email", "email_verified"]
}'
Authlete は認可時に指定された consentedClaims をデータベースに保存し、/auth/userinfo や /auth/introspection の応答に含めます。
ここで
consentedClaimsに指定するクレームはあらかじめ対象サービスのトークン&クレーム>クレーム>サポート可能なクレームに追加しておく必要がある点に注意してください。![]()
>
先ほどの認可リクエストに紐づくトークンを Userinfo Request API に送信すると以下のような応答が得られます。
curl --request POST \
--url https://jp.authlete.com/api/{{serviceId}}/auth/userinfo \
--header 'authorization: Bearer {{serviceAccessToken}}' \
--header 'content-type: application/json' \
--data '{"token": "{{accessToken}}"}'
{
"action": "OK",
"clientId": 1110197986,
"subject": "john",
"scopes": [
"email",
"openid"
],
"claims": [
"email",
"email_verified"
],
"token": "ytaniPwocUVRSDuCBn6EEIR7SYYRxIHkmvv2ht7oPLU",
"clientIdAlias": "rest-client-client",
"clientIdAliasUsed": true,
"clientEntityIdUsed": false,
"consentedClaims": [
"name",
"username",
"email",
"email_verified"
],
"resultCode": "A091001",
"resultMessage": "[A091001] The access token presented at the userinfo endpoint is valid."
}
OpenID プロバイダーは claims 応答の代わりに、consentedClaims 応答を参照し、ユーザーが提供に同意したクレームを Userinfo エンドポイントの応答として返却することが可能となります。
curl --request POST \
--url https://jp.authlete.com/api/{{serviceId}}/auth/userinfo/issue \
--header 'authorization: Bearer {{serviceAccessToken}}' \
--header 'content-type: application/json' \
--data '{"token": "{{accessToken}}",
"claims": "{
\"name\": \"John Doe\",
\"username\": \"jdoe\",
\"email\": \"john@example.com\",
\"email_verified\": true}"
}'
上記リクエストの結果、Userinfo エンドポイントから、以下のようにユーザーが提供に同意した氏名とユーザー名、メールアドレスを含む応答が得られます。
{
"action": "JSON",
"responseContent": "{\"sub\":\"john\",\"name\":\"John Doe\",\"email\":\"john@example.com\",\"email_verified\":true,\"username\":\"jdoe\"}",
"resultCode": "A096001",
"resultMessage": "[A096001] User information was obtained successfully."
}