8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

実装者による OIDC4IDA 解説

Last updated at Posted at 2022-05-09

はじめに

OpenID Connect for Identity Assurance 1.0 (OIDC4IDA または IDA) は、OpenID FoundationeKYC-IDA ワーキンググループが開発した技術仕様です。当仕様は OAuth 2.0OpenID Connect (OIDC) を基盤とし、自然人の検証済みクレームを格納する JSON 構造を定義します。

ida-stack_ja.png

ここでの『クレーム』は技術用語で、名前、誕生日、住所等のユーザー属性を意味しています。

ここでの『検証済み』とは、パスポートや運転免許証等の証拠によってクレームの真正性が検証済みであることを意味しています。

インターネット上にはユーザー登録可能なウェブサービスがたくさんあります。それらの多くは属性情報の登録をユーザーに求めますが、登録されるデータはユーザーが自己申告したものに過ぎず、法的な文脈では利用できません。ここで OIDC4IDA が登場します。

※ 本記事の英語版はこちら → "OpenID Connect for Identity Assurance, explained by an implementer"

歴史

  • 実装者向け草稿第一版: 2019 年 11 月に公表された仕様の初版です。この版は Implementer's Draft 1 (ID1) と呼ばれます。

  • 実装者向け草稿第二版: 2020 年 5 月に公表された二番目の版です。この版は Implementer's Draft 2 (ID2) と呼ばれます。

  • 実装者向け草稿第三版: 2021 年 11 月に公表された三番目の版です。この版は Implementer's Draft 3 (ID3) と呼ばれます。本記事執筆時点 (2022 年 5 月) では、公式に公開された草稿の中では最新版です。

  • 次の草稿: これまでの実装者向け草稿は破壊的変更を繰り返してきました。そして再び、次の版にも破壊的変更が含まれることが確定しています。というのは、既に破壊的変更 (例:PR 87) が eKYC-IDA WG の Git レポジトリ の master ブランチにマージ済みだからです。破壊的変更と追加された新しいプロパティー群の量を考慮すると、将来の最終版の前に実装者向け草稿第四版が公開される可能性はかなり高いでしょう。

ida-history_ja.png

本記事の執筆者 (私) は eKYC-IDA WG の定例会議に出席しており、仕様の最新情報を読者の皆様と共有することが可能なので、本記事は eKYC-IDA Git レポジトリ内の最新仕様に基づいて書くことにします。

verified_claims

仕様は検証済みクレームを格納する JSON 構造を定義します。その JSON 構造は、ID トークン (OIDC Core, Section 2) のペイロード部やユーザー情報エンドポイント (OIDC Core, Section 5.3) からのレスポンスなどの他の JSON 構造に埋め込まれることを想定しています。

当 JSON 構造が他の JSON 構造内に埋め込まれる際は、"verified_claims" というプロパティー・キーが与えられます。次の図は ID トークンのペイロード部にどのように埋め込まれるかを示しています。

verified_claims_in_id_token.png

"verified_claims" の構造は JSON スキーマファイル verified_claims.json に記述されています。このファイルは eKYC-IDA Git レポジトリの schema ディレクトリで管理されています。

verification と claims

"verified_claims" JSON オブジェクトは、"verification""claims" をトップレベルのプロパティーとして含んでいます。

"verification" JSON オブジェクトは、検証プロセスに関する情報、例えば「どの法規に基づくものか?」「どの証拠を使って?」「いつ?」「誰によって?」という情報を含んでいます。

"claims" JSON オブジェクトは、検証済みクレーム群の名前と値の組を含んでいます。

verification-and-claims.png

verified_claims リクエスト

ID トークンやユーザー情報レスポンスに "verified_claims" を埋め込むよう認可サーバーに要求するため、クライアントアプリケーションは OpenID Connect Core 1.0Section 5.5 で定義されている claims リクエストパラメーターを使います。

claims リクエストパラメーターのフォーマットは JSON です。その JSON には、"id_token""userinfo" のどちらかまたは両方がトップレベルのプロパティーとして含まれます。クライアントアプリケーションは、ID トークンに埋め込んでほしいクレーム群の名前を JSON オブジェクト "id_token" 内に列挙します。同様に、ユーザー情報レスポンスに埋め込んでほしいクレーム群の名前を JSON オブジェクト "userinfo" 内に列挙します。この規則は OIDC Core 仕様に書かれています。

claims-request-parameter_ja.png

検証済みクレームを取得したければ、下図が示すように、クライアントアプリケーションは JSON オブジェクト "id_token" や JSON オブジェクト "userinfo""verified_claims" を含めます。

verified_claims-in-claims_ja.png

"verified_claims" リクエストの構造は JSON スキーマファイル verified_claims_request.json に記述されています。このファイルは eKYC-IDA Git レポジトリの schema ディレクトリで管理されています。

データ最小化

サーバーは明示的に要求されていないデータを返却してはならないと仕様で定められています。このポリシーはデータ最小化 (data minimization) と呼ばれます。そのため、次のような単純な verified_claims リクエストに対しては、

{
  "userinfo": {
    "verified_claims": {
      "verification": {
        "trust_framework": null
      },
      "claims": {
        "given_name": null
      }
    }
  }
}

次に示すように、サーバーは "trust_framework""given_name" しか返しません。

{
  "verified_claims": {
    "verification": {
      "trust_framework": "nist_800_63A"
    },
    "claims": {
      "given_name": "Inga"
    }
  }
}

クライアントアプリケーションがもっと情報をほしければ、複雑な verified_claims リクエストを構築しなければなりません。次のものは (仕様書から抜粋した) 複雑な verified_claims リクエストを含む claims パラメーターの値の例です。

{
  "userinfo": {
    "verified_claims": {
      "verification": {
        "trust_framework": null,
        "time": null,
        "evidence": [
          {
            "type": {
              "value": "document"
            },
            "method": null,
            "document_details": {
              "type": null
            }
          }
        ]
      },
      "claims": {
        "given_name": null,
        "family_name": null,
        "birthdate": null
      }
    }
  }
}

フィルタリング

value, values, max_age による制約

verified_claims リクエスト内のクレームが、"value", "values", "max_age" を含む JSON オブジェクトを伴い、かつ、それが verified_claims/verification 以下にあるなら (つまり verified_claims/claims 以下でなければ)、その JSON オブジェクトはフィルタリングの条件として使用されます。

プロパティー名 説明
"value" クレームの実際の値は "value" で指定された値と一致しなければならない。
"values" クレームの実際の値は "values" 配列内のいずれかの要素と一致しなければならない。
"max_age" クレームの実際の値が示す日時からの経過時間は "max_age" で指定された秒数を超えてはならない。

value の例

次の例は、トラストフレームワーク uk_tfida のルールで検証された検証済みクレームを要求します。サーバーが条件を満たす検証済みクレームを保持していない場合、"verified_claims" は返却されません。

{
  "userinfo": {
    "verified_claims": {
      "verification": {
        "trust_framework": {
          "value": "uk_tfida"
        }
      },
      "claims": {
        "given_name": null
      }
    }
  }
}

values の例

次の例は、トラストフレームワーク nist_800_63A または uk_tfida のルールで検証された検証済みクレームを要求します。

{
  "userinfo": {
    "verified_claims": {
      "verification": {
        "trust_framework": {
          "values": [ "nist_800_63A", "uk_tfida" ]
        }
      },
      "claims": {
        "given_name": null
      }
    }
  }
}

max_age の例

次の例は、アイデンティティ検証プロセスが実施された日時からの経過時間が 30 日 (= 2,592,000 秒) を超えていないことを要求します。サーバーが 30 日以内に検証された検証済みクレームを保持していない場合、"verified_claims" は返却されません。

{
  "userinfo": {
    "verified_claims": {
      "verification": {
        "trust_framework": null,
        "time": {
          "max_age": 2592000
        }
      },
      "claims": {
        "given_name": null
      }
    }
  }
} 

配列による論理和

仕様の「Requesting Verification Data」セクションには evidence 配列に対する興味深い要求事項があります。

A single entry in the evidence array represents a filter over elements of a certain evidence type. The RP therefore MUST specify this type by including the type field including a suitable value sub-element value. The values sub-element MUST NOT be used for the evidence/type field.

If multiple entries are present in evidence, these filters are linked by a logical OR.

結果として、次のリクエストにより、"type""document" もしくは "electronic_signature" である証拠が全て "verified_claims" に含まれることになります。

{
  "userinfo": {
    "verified_claims": {
      "verification": {
        "trust_framework": null,
        "evidence": [
          {
            "type": {
              "value": "document"
            },
            "method": null,
            "document_details": {
              "type": null,
              "document_number": null
            }
          },
          {
            "type": {
              "value": "electronic_signature"
            },
            "signature_type": null,
            "issuer": null,
            "serial_number": null
          }
        ]
      },
      "claims": {
        "given_name": null
      }
    }
  }
}

この特別規則は check_details などの他の配列型プロパティー群にも適用されます。しかし、assurance_details については特別規則があります。下記は当規則を仕様書から抜粋したものです。

assurance_details is an array representing how the evidence and check_details meets the requirements of the trust_framework. RP SHOULD only request this where they need to know this information. Where assurance_details have been requested by an RP the OP MUST return the assurance_details element along with all sub-elements that it has. If an RP wants to filter what types of evidence and check_methods they MUST use those methods to do so, e.g. requesting an assurance_type should have no filtering effect.

つまり、assurance_details を要求すると、当プロパティーの全ての下位要素が返却されます。データ最小化や配列による論理和は適用されません。

データ最小化とフィルタリングの例

次の JSON の内容と同等のデータセットをサーバーが保持しているものとします。

{
  "verification": {
    "trust_framework": "uk_tfida",
    "evidence": [
      {
        "type": "electronic_record",
        "check_details": [
          {
            "check_method": "kbv",
            "organization": "TheCreditBureau",
            "txn": "kbv1-hf934hn09234ng03jj3"
          }
        ],
        "time": "2021-04-09T14:12Z",
        "record": {
          "type": "mortgage_account",
          "source": {
            "name": "TheCreditBureau"
          }
        }
      },
      {
        "type": "electronic_record",
        "check_details": [
          {
            "check_method": "kbv",
            "organization": "OpenBankingTPP",
            "txn": "kbv2-nm0f23u9459fj38u5j6"
          }
        ],
        "time": "2021-04-09T14:12Z",
        "record": {
          "type": "bank_account",
          "source": {
            "name": "TheBank"
          }
        }
      }
    ]
  },
  "claims": {
    "given_name": "Sarah",
    "family_name": "Meredyth",
    "birthdate": "1976-03-11",
    "place_of_birth": {
      "country": "UK"
    },
    "address": {
      "locality": "Edinburgh",
      "postal_code": "EH1 9GP",
      "country": "UK",
      "street_address": "122 Burns Crescent"
    }
  }
}

このとき、当該データセットに対して次の verified_claims リクエストが行われた場合、

{
  "verification": {
    "trust_framework": null,
    "evidence": [
      {
        "type": {
          "value": "electronic_record"
        },
        "check_details": [
          {
            "check_method": null,
            "organization": {
              "value": "OpenBankingTPP"
            },
            "txn": null
          }
        ]
      }
    ]
  },
  "claims": {
    "given_name": null,
    "family_name": {
      "value": "Unknown"
    },
    "address": {
      "locality": null
    }
  }
}

サーバーは次の "verified_claims" を生成すべきです。

{
  "verification": {
    "trust_framework": "uk_tfida",
    "evidence": [
      {
        "type": "electronic_record",
        "check_details": [
          {
            "check_method": "kbv",
            "organization": "OpenBankingTPP",
            "txn": "kbv2-nm0f23u9459fj38u5j6"
          }
        ]
      }
    ]
  },
  "claims": {
    "given_name": "Sarah",
    "address": {
      "locality": "Edinburgh"
    }
  }
}

要点は次のとおりです。

  1. サーバー側のデータセットでは "evidence" 配列に要素が 2 つ含まれているものの、生成された "verified_claims" には要素が 1 つしかありません。これは、check_details/*/organization == "OpenBankingTPP" という制約条件を満たさない要素が取り除かれたためです。

  2. 生成された "verified_claims" には "family_name" クレームが含まれていません。これは、サーバー側のデータセットにおいて、"family_name" の実際の値が "Unknown" ではないからです。"value", "values", "max_age" 制約が verified_claims/verification 以下で使われた場合、不一致のプロパティーを含むデータセットの全体または一部が省略されます。一方で、verified_claims/claims 以下では、不一致のプロパティーは他の部分に影響を与えることなく、それのみが省略されます。

  3. データ最小化ポリシーのため、生成された "verified_claims" では多くのプロパティーが省略されています。例えば、"address" には "locality" しか含まれていません。"postal_code", "country", "street_address" といった他のプロパティーは省略されています。

アタッチメント

実装者向け草稿第三版で追加されたものの中でも、アタッチメントは比較的大きな機能です。この機能により、アイデンティティ検証プロセスに関連のあるメディアを添付することが可能になります。例えば、署名フォームのスキャンや証拠の写真などです。

アタッチメントは、下記が示すように "attachments" 配列に直接埋め込むことができます。次の例は eKYC-IDA Git レポジトリにある embedded_attachments.json のコピーです。

{
  "verified_claims": {
    "verification": {
      "trust_framework":"eidas",
      "assurance_level": "substantial",
      "evidence": [
        {
          "type": "document",
          "method": "pipp",
          "time": "2012-04-22T11:30Z",
          "document_details": {
            "type": "idcard",
            "issuer": {
              "name": "Stadt Augsburg",
              "country": "DE"
            },
            "document_number": "53554554",
            "date_of_issuance": "2010-03-23",
            "date_of_expiry": "2020-03-22"
          },
          "attachments": [
            {
              "desc": "Front of id document",
              "content_type": "image/png",
              "content": "Wkd0bWFtVnlhWFI2Wlc0Mk16VER2RFUyY0RRMWFUbDBNelJ1TlRjd31dzdaM1pTQXJaWGRsTXpNZ2RETmxDZwo="
            },
            {
              "desc": "Back of id document",
              "content_type": "image/png",
              "content": "iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAYAAABytg0kAADSFsjdkhjwhAABJRU5ErkJggg=="
            }
          ]
        }
      ]
    },
    "claims": {
      "given_name": "Max",
      "family_name": "Mustermann",
      "birthdate": "1956-01-28"
    }
  }
}

また、アタッチメントの内容がリモートサーバー上に置かれているケースでは、アタッチメントの URL のみを (任意でアクセストークンを添えて) "attachments" 配列に含めることができます。次の例は eKYC-IDA Git レポジトリにある external_attachments.json のコピーです。

{
  "verified_claims": {
    "verification": {
      "trust_framework":"eidas",
      "assurance_level": "substantial",
      "evidence": [
        {
          "type": "document",
          "method": "pipp",
          "time": "2012-04-22T11:30Z",
          "document_details": {
            "type": "idcard",
            "issuer": {
              "name": "Stadt Augsburg",
              "country": "DE"
            },
            "document_number": "53554554",
            "date_of_issuance": "2010-03-23",
            "date_of_expiry": "2020-03-22"
          },
          "attachments": [
            {
              "desc": "Front of id document",
              "digest": {
                "alg": "sha-256",
                "value": "qC1zE5AfxylOFLrCnOIURXJUvnZwSFe5uUj8t6hdQVM="
              },
              "url": "https://example.com/attachments/pGL9yz4hZQ",
              "access_token": "ksj3n283dke",
              "expires_in": 30
            },
            {
              "desc": "Back of id document",
              "digest": {
                "alg": "sha-256",
                "value": "2QcDeLJ/qeXJn4nP+v3nijMgxOBCT9WJaV0LjRS4aT8="
              },
              "url": "https://example.com/attachments/4Ag8IpOf95"
            },
            {
              "desc": "Signed document",
              "digest": {
                "alg": "sha-256",
                "value": "i3O7U79LiyKmmesIgULKT2Q8LAxNO0CpwJVcbepaYf8="
              },
              "url": "https://example.com/attachments/4Ag8IpOf95",
              "access_token": null,
              "expires_in": 30
            }
          ]
        }
      ]
    },
    "claims": {
      "given_name": "Max",
      "family_name": "Mustermann",
      "birthdate": "1956-01-28"
    }
  }
}

変換クレーム

変換クレーム (Transformed Claim; TC) は OIDC4IDA 仕様の一部ではありませんが、eKYC-IDA WG で議論されている仕様群の一つである OpenID Connect Advanced Syntax for Claims (ASC) 1.0 の一部です。

紹介

変換クレーム機能は、変換関数 (transformation function) を適用することでクレーム値の変換を可能にします。

例えば、birthdate クレームに years_ago 変換関数を適用してユーザーの年齢を計算し、ID トークンやユーザー情報レスポンスに埋め込むことができます。さらに、years_ago 変換関数の結果に対して、引数 18 を伴う gte 変換関数 (gte は "Greater Than or Equal to" の意) を適用することで、ユーザーが 18 歳以上かどうかを示す真偽値を得ることができます。この例は、「年齢確認 (age verification) が必要なものの誕生日等の個人情報は極力開示すべきではない」というシナリオで使うことができます。

tc-concept_ja.png

TC 仕様に注目すべき理由は、インターネット上に世界規模の高信頼デジタルアイデンティティネットワークの構築を目指す GAIN (Global Assured Identity Network) プロジェクトのホワイトペーパーに載せられているシナリオで年齢確認が鍵となる要素の一つとなっているからです。

変換クレームの定義

変換クレームは次の要素で成り立っています。

  1. 変換クレームの名前
  2. 入力として参照するクレーム
  3. 入力に対して適用する変換関数群 (引数を必要とするものもある)

『変換クレームの例』の図で、age_18_or_over が変換クレームの名前、birthdate が参照するクレーム、years_ago と (引数 18 を伴う) gte が適用する変換関数群です。

変換クレームは JSON オブジェクト内のプロパティーとして定義されます。プロパティーのキーが変換クレームの名前で、プロパティーのバリューは claim プロパティーと fn プロパティーを含む JSON オブジェクトです。claim プロパティーは参照するクレームを示し、fn プロパティーは変換関数のリストです。

例えば、age_18_or_over 変換クレームは次のように定義することができます。

{
  "age_18_or_over": {
    "claim": "birthdate",
    "fn": [
      "years_ago",
      [ "gte", 18 ]
    ]
  }
}

fn プロパティーの値は配列です。配列の各要素は変換関数であり、引数が伴っている場合もあります。変換関数が引数を取らない場合は変換関数の名前のみが fn 配列内に書かれます (例: "years_ago")。一方、変換関数が引数を取る場合、変換関数の名前と引数群をまとめた配列が fn 配列内に書かれます (例: ["gte", 18])。

変換クレームの定義を置く場所

変換クレームの定義を置く場所は 2 つあります。一つは認可リクエストの claims リクエストパラメーター (OIDC Core, Section 5.5) です。もう一方は認可サーバーのディスカバリードキュメント (OIDC Discovery, Section 4) です。

transformed_claims

仕様では、claims リクエストパラメーター内の新しいプロパティーとして transformed_claims が定義されます。クライアントアプリケーションは変換クレーム群の定義をそこに書きます。

次の JSON は claims リクエストパラメーターの内容の例です。age_18_or_over 変換クレームの定義を含む "transformed_claims" が含まれています。

{
  "transformed_claims": {
    "age_18_or_over": {
      "claim": "birthdate",
      "fn": [
        "years_ago",
        [ "gte", 18 ]
      ]
    }
  },
  "id_token": {
    "verified_claims": {
      "verification": {
        "trust_framework": null
      },
      "claims": {
        "given_name": null,
        ":age_18_or_over": null
      }
    }
  }
}

この例でもう一つ言及しておくべき点は、定義された変換クレームの参照のされ方です。"transformed_claims" で定義された変換クレームが "claims" 内で参照されるとき、:age_18_or_over のように、コロン (:) が前置されます。

transformed_claims_predefined

仕様は、新しいサーバーメタデータとして transformed_claims_predefined を定義しています。認可サーバーは変換クレームの定義をそこに置くことができます。

次の JSON は transformed_claims_predefined サーバーメタデータの例です。

{
  "transformed_claims_predefined": {
    "age_100_or_over": {
      "claim": "birthdate",
      "fn": [
        "years_ago",
        [ "gte", 100 ]
      ]
    }
  }
}

クライアントアプリケーションは、認可サーバーが事前定義した変換クレームを再定義することなく利用可能です。次の JSON は claims リクエストパラメーターの値の例で、二つのコロン (::) を前置することにより事前定義された変換クレームを参照しています。

{
  "id_token": {
    "verified_claims": {
      "verification": {
        "trust_framework": null
      },
      "claims": {
        "given_name": null,
        "::age_100_or_over": null
      }
    }
  }
}

変換関数の連結

変換クレーム定義内の fn プロパティーは変換関数のリストです。リスト内の一番目の変換関数は既知のクレームを入力として受け取ります。二番目以降の変換関数は、それぞれの直前の変換関数の実行結果を入力として受け取ります。最後の変換関数の実行結果は、変換クレームの値として使用されます。

例えば、先に挙げた例では、years_ago 変換関数が birthdate クレームの値を受け取り、実行結果として、例えば 30 を生成します。その後、gte 変換関数が 30 を入力として受け取り、実行結果として true を生成します。gte が生成したこの true が、age_18_or_over 変換クレームの値となります。

tc-chain_ja.png

定義済みの変換関数

次の変換関数群は仕様で事前定義されています。詳細については ASC 仕様を参照してください。

変換関数 説明
years_ago 入力値からの経過年数を計算する。
eq 入力値と引数が等しければ真。
gt 入力値が引数よりも大きければ真。
lt 入力値が引数よりも小さければ真。
gte 入力値が引数以上であれば真。
lte 入力値が引数以下であれば真。
hash 入力値のハッシュ値を計算する。
any 入力配列のいずれかの要素が真ならば真。
all 入力配列の全ての要素が真ならば真。
none 入力配列の全ての要素が偽ならば真。
get 入力 JSON オブジェクトから指定されたプロパティーの値を取得する。
match 入力値が引数で指定された正規表現にマッチすれば真。

変換クレームのデモ

2021 年 12 月 1 日、OAuth Security Workshop のセッションで本記事の筆者 (私) が変換クレームのデモを行いました。その録画が YouTube にあがっています。デモは 28 分 32 秒から始まります。

実装

データ最小化とフィルタリングの実装

OIDC4IDA 仕様を妥協せずに実装し始めるとすぐに、データ最小化ポリシーとフィルタリング規則のロジックを実装するのが難しいことに気付くでしょう。

OIDC Core では、(address クレーム を除き) 全てのクレームは ID トークンのペイロード部やユーザー情報レスポンスのトップレベルプロパティーとしてフラットに列挙されます。しかし、"verified_claims" リクエストの構造は複雑過ぎます。

落胆しているかもしれない開発者の方々のため、当該ロジックの実装をオープンソースとして公開しました。

DatasetExtractor クラスは authlete-java-common ライブラリの一部です。当ライブラリは Authlete 用ですが、当クラス内に実装されているロジックは Authlete API からは独立しています。そのため、ロジックをあなたの環境に移植することは可能です。

変換クレームの実装

私の知る限り、本記事執筆時点 (2022 年 5 月) において、変換クレームの実装は世界に Authlete 2.3 しかありません。変換クレームの機能は Authlete サーバーに実装されており、オープンソースではありません。変換クレームを試したい方は Authlete 社までお問い合わせください。

認可サーバーの実装

java-oauth-server はオープンソースの認可サーバーサンプル実装です。java-oauth-server は Authlete をバックエンドシステムとして使用します。Authlete はフロントエンドの認可サーバーに代わり、OAuth/OIDC リクエストの解釈、アクセストークンの生成管理、OAuth/OIDC レスポンスの準備をおこないます。

最新の IDA 仕様と変換クレームをサポートする Authlete 2.3 を使うように java-oauth-server を設定すれば、この記事で説明されている仕様を試すことができます。

次のものは java-oauth-server に対する認可リクエストの例です。

http://localhost:8080/api/authorization?client_id=7681191256&redirect_uri=http://localhost:4000/api/mock/redirection/5383012317&response_type=id_token&scope=openid+email&state=q4sa5o7g6y&nonce=n-0S6_WzA2Mj&claims={"id_token":{"verified_claims":{"verification":{"trust_framework":null,"assurance_process":{"assurance_details":[{"assurance_type":{"value":"verification"},"assurance_classification":null,"evidence_ref":{"txn":null}}]},"verification_process":null,"evidence":[{"type":{"value":"document"},"check_details":[{"check_method":{"value":"pvp"},"organization":null,"txn":null}],"time":null}]},"claims":{"given_name":null,"family_name":null,"address":{"street_address":null,"locality":null,"country":null},"::age_100_or_over":null,":age_18_or_over":null}}},"transformed_claims":{"age_18_or_over":{"claim":"birthdate","fn":["years_ago",["gte",18]]}}}

次の jSON は、上記の認可リクエストの claims パラメーターの値を見やすく整形したものです。

{
  "id_token": {
    "verified_claims": {
      "verification":{
        "trust_framework": null,
        "assurance_process": {
          "assurance_details": [
            {
              "assurance_type": {
                "value": "verification"
              },
              "assurance_classification": null,
              "evidence_ref": {
                "txn": null
              }
            }
          ]
        },
        "verification_process": null,
        "evidence": [
          {
            "type": {
              "value": "document"
            },
            "check_details": [
              {
                "check_method": {
                  "value": "pvp"
                },
                "organization": null,
                "txn": null
              }
            ],
            "time":null
          }
        ]
      },
      "claims": {
        "given_name": null,
        "family_name": null,
        "address": {
          "street_address": null,
          "locality": null,
          "country": null
        },
        "::age_100_or_over": null,
        ":age_18_or_over": null
      }
    }
  },
  "transformed_claims": {
    "age_18_or_over": {
      "claim": "birthdate",
      "fn": [
        "years_ago",
        [ "gte", 18 ]
      ]
    }
  }
}

この認可リクエストに対して java-oauth-server は次のような認可ページを表示します。

authorization_endpoint.png

最新 IDA 仕様のテスト用アカウントは inga です (ログイン ID = inga, パスワード = inga)。アカウントの検証済みクレームは document_800_63A.json ファイルと document_UKTDIF.json ファイルから読み込まれます。これらのファイルは eKYC-IDA Git レポジトリexamples/response ディレクトリからコピーしたものです。

ログイン ID とパスワードの入力欄に ingainga を入れ、Authorize ボタンを押すと、ウェブブラウザは java-oauth-server 上にあるリダイレクションエンドポイントにリダイレクトされます。

リダイレクションエンドポイントの JavaScript は、エンドポイントが受け取ったパラメーター群を表示します。次のような表示になります。

redirection_endpoint.png

発行された ID トークンのペイロード部は次のようになります。データ最小化やフィルタリングが機能していること、変換クレームが verified_claims/claims に含まれていることを確認できます。

{
  "iss": "https://authlete.com",
  "sub": "1004",
  "aud": [
    "7681191256"
  ],
  "exp": 1651654999,
  "iat": 1651568599,
  "auth_time": 1651568599,
  "nonce": "n-0S6_WzA2Mj",
  "s_hash": "tEu5XMDHP5FQWevcuhLohQ",
  "email": "inga@example.com",
  "email_verified": false,
  "verified_claims": {
    "verification": {
      "trust_framework": "nist_800_63A",
      "assurance_process": {
        "assurance_details": [
          {
            "assurance_type": "verification",
            "assurance_classification": "strong",
            "evidence_ref": {
              "txn": "v-93jfk284ugjfj2093"
            }
          }
        ]
      },
      "verification_process": "7675D80F-57E0-AB14-9543-26B41FC22",
      "evidence": [
        {
          "type": "document",
          "check_details": [
            {
              "check_method": "pvp",
              "organization": "face_checker",
              "txn": "v-93jfk284ugjfj2093"
            }
          ],
          "time": "2021-06-06T05:33Z"
        }
      ]
    },
    "claims": {
      "given_name": "Inga",
      "family_name": "Silverstone",
      "address": {
        "street_address": "114 Old State Hwy 127",
        "locality": "Shoshone",
        "country": "USA"
      },
      "::age_100_or_over": false,
      ":age_18_or_over": true
    }
  }
}

さいごに

複雑さや不安定さのため、OIDC4IDA 仕様の進化についていくのは大変です。しかし、OAuth/OIDC サーバーのバックエンドシステムとして Authlete を使うことにより、その大変な部分を Authlete 社のドメイン・エキスパートに任せることができます。

OAuth, OpenID Connect, Financial-grade API, Identity Assurance 及びその他の関連標準仕様の高品質かつ最先端の実装が必要になった際は Authlete 社にお問い合わせください。

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?