OpenID ConnectのUserInfo Endpointとは?

こんばんは、お久しぶりです、ritouです。
特に何かの準備というわけではありませんが、最近なんとなく気になってOpenID Connectの仕様をキャッチアップしています。

今まで何度も取り上げているこのOpenID Connect、"良い意味で"仕様が細かくわかれています。
普通であればCoreから紹介していくべきですが、空気を読まず今回はRPがユーザーの属性などを取得するためにアクセスする、UserInfo Endpointについての仕様を紹介します。

あの有名なエントリでは、「ユーザーの属性情報と他のサイトのロッカーの鍵が入った鍵付きロッカー」のような説明がされています。
具体的にはどうなっているのか、仕様を見ていきます。

UserInfo Endpointとは

  • 認証されたユーザーのクレームを返す
  • クレームオブジェクトはJSON形式で表現され、個々のクレームとクレームの値であるメンバーとその値で構成される

リクエス

UserInfo Endpointへのリクエストは、基本的にOAuth 2.0ベースなため、パラメータは以下のようになります。

  • access_token : 【必須】OpenID Connectのフローで取得したAccess Token
  • schema : 【任意】このEndpointから返されるデータのスキーマ。今のところ"openid"だけ。このパラメータが含まれない場合はIdPの後方互換のために独自のレスポンスが返されるかも。
  • id : 【予約】for backwards compatibilityとあります。schemaに"openid"が指定されたら無視する。

レスポンス

リクエストのschemaが"openid"であれば、レスポンスはPortable Contactsの一部をプレインテキストJSONオブジェクトで返されます。
クレームは単純なbooean値"true"/"false"から複雑な組み合わせまでいろいろあり、内容は以下の通り。

(仕様のこの部分にあるmultiple languages and scriptsとかの部分に@_nat氏のこだわりを感じつつも、省略させていただきます)

  • displayName : 表示名
  • nickname : ニックネーム
  • name : 名前関係。"formatted","familyName", "givenName", "middleName", "honorificPrefix", "honorificSuffix"などなどなど
  • photos : プロフィール画像のURL
  • emails : メアド。任意の"type",booleanの"primary"属性を持ってもよい。加えて、確認済みかどうかを示すbooleanの"verified"属性も定義されている。
  • phoneNumbers : 電話番号
  • urls : Webサイト等のURL。任意の"type"属性は"blog"や"profile"などの内容を示す。
  • birthday : YYYY-MM-DD形式のおたんじょうび!お年がわからないor教えたくない人は年の部分に0000をセットしてもよいらしい。
  • updated : ユーザー情報の最終更新日。"full UTC date-time format"で表現されるということで、1990-12-31T23:59:60Zとか?1990-12-31T15:59:60-08:00とか?
  • gender : 性別 "male", "female", "undisclosed"+独自定義の値。つまり、男も女もハ○フも表現可能ですね。
  • addresses : 住所関係。"formatted", "streetAddress", "locality", "region", "postalCode", "country"
  • utcOffset : タイムゾーンオフセット。
  • language : 言語。ISO639形式

OpenID Auth 2.0には、属性交換のAXってのがありますね。
OpenID Connectにおいても、RPは、OPに対してAuthZ Endpointへリクエストを送る際にこのレスポンスの形式や内容について指定することができます。
その内容については、OpenID Connect Coreの4.1.1.1. OpenID Request Objectにあります。
詳細はCoreの仕様紹介の際にするとして、ざっくり次のように指定できます。

  • 要求するクレームのリスト
  • 要求するクレームの形式(unsigned JSON object/signed JWT/signed and encrypted JWT)

下記の例では、infがUserInfo Endpointに関するリクエスト、clmがクレームリスト、fmtが形式を示しています。

{
 "inf":
   {
     "clm":
       {
         "name": null,
         "displayName": {"opt": true},
         "emails": null,
         "photos": {"opt": true},
       },
     "fmt": "sig"
   }
 "ses":
   {
     "clm":
       {
        "aat": null
       }
     "mxa": 86400,
     "eaa": 2
   }
}

サンプルレスポンス

{
"name": {"givenName": "Jane", "familyName": "Doe"},
"displayName": "Jane Doe",
"emails": [
              {"value": "janedoe@example.com", "primary": true, "verified": true}
          ],
"photos": [
              {"value": "https://example.com/profiles/janedoe/photo.jpg", "type": "photo"},
              {"value": "https://example.com/profiles/janedoe/thumb.jpg", "type": "thumbnail"}
          ]
}

まとめ

現在の仕様では、属性の提供方法が指定してあります。
そういえば、PoCo以外にも、Schema.orgとかも絡んでくるのか気になりますね。
今後、クレーム集約、分散クレームに関する部分で他のWebサービスAccess Tokenなどもこの仕様か別のもので定義されるかもしれません。
ということで、この仕様がどうなっていくかは注目です。

次はDynamic Registration関連でも見てみましょうか。
ではまた。