去る2020年1月24日に、OpenID ファウンデーション・ジャパン主催で「OpenID Summit Tokyo 2020」が開催されました。本イベントは、日本におけるOpenIDおよびその周辺技術・ビジネスのイベントです。
今回は、SalesforceのVice President, Identity Product Managementの Ian Glazer氏や、デジタル・アイデンティの父と呼ばれたKim Cameron氏、 MicrosoftのIdentity Architect の Michael B. Jones氏 がキーノートに登壇し、日本からも、経済産業省 CIO補佐官 満塩尚史氏や、国立情報学研究所の山地一禎氏など多くの著名人が登壇されました。
NRIセキュアは、技術セッションにて、新たなユーザー体験を支える新しい認証・認可の技術仕様「OpenID Connect Client Initiated Backchannel Authentication Flow」(OpenID Connect CIBA、 以下「CIBA」 と記載します。)の実装例と、実装時に考慮しなければならないポイントについて講演しました。本記事は、その講演内容をもとに作成しました。全資料はこちらからダウンロードできます。
注:本記事の講演内容は2019年12月時点のものです。最新の仕様とは異なる可能性があります。
OpenID Connect CIBAとは
Open ID Connect CIBAの中身を説明する前に、まずは「CIBA」の考え方を整理したいと思います。
OpenID Connect Coreでは、認可、認証の代表的なプロセスとして、認可コードフローが定義されています。しかし、「サービスを利用」するユーザー自身が「認証/認可」を行う流れが一般的で、多様なデバイス(例えば、スマートスピーカーやIoT、POSなど)への対応や、第三者がユーザーの同意に基づいてAPIを実行できるような仕様にはなっていませんでした。
そこで、「サービス利用」と「認証/認可」を行うデバイス・ユーザーを分離したいというユースケースを実現するために生まれた考え方が「CIBA」です。
例えば、下記のように、決済や認証のデバイスが多岐にわたる場合や、ユーザーと実行する人が、別の人物である場合などに有効です。
- 銀行窓口処理を、Web上でユーザーの同意を得て、受付担当者に実行させたい
- POS端末での決済を、ユーザーのスマートフォン上で許可したい
- 子の(親のカードを使った)支払いを、親がスマートフォン上で許可したい
OpenID Connect CIBA 実装デモ
講演当日は、「子の(親のカードを使った)支払いを親がスマートフォンで承認したい」のデモを実装し、解説しました。デモの流れを簡単に説明すると、以下の通りになります。
- 子供が、自身のPCでECサイトにアクセスし、親名義の家族カードで決済しようとする
- 決済に対する同意の要求が、親が持つスマートフォンへプッシュ通知される
- 親が自身のスマートフォンで、認証・同意を行う
- 子供が利用しているブラウザ側で決済完了となる
当日行ったデモのイメージは以下の動画をご参照下さい。
画面の左側が、子が操作するブラウザ(後述のConsumption Device)、右側が、親が操作するスマホ(後述の Authentication Device )の画面をミラーリングしたものになります。
なお、デモにあるFIDO UAFによる生体認証の処理は、Uni-ID Libraのオプションで実行できる処理で、CIBAの仕様ではありません。
CIBAの実装アーキテクチャ
今回のデモでは、下図のようなアーキテクチャで実装しています。
認可サーバー(OP:OpenID Provider)には、弊社の製品である「Uni-ID Libra」を利用しています。Uni-ID Libraのモジュールをデプロイし、Webサーバーを起動すると、OpenID ConnectのOPとして動作します。OPの機能として、多要素認証や、FIDO UAFやWebAuthnなどのパスワードレス認証の仕組み、なりすましログインなどの検知機能、ユーザー自身による管理機能(新規登録、PWリセット、属性参照など)や外部IdPによる認証機能などを提供しています。Uni-ID Libraの詳細はこちらを参照してください。
デモ動画上で親が所有するスマートフォンへのプッシュ通知を行っています。こちらのプッシュ通知の基盤として、Firebase Cloud Messaging(FCM)を利用しています。その他、プッシュ通知を受けるスマートフォンアプリや、デモ用のECサイトを実装しました。
OpenID Connect CIBAの仕様
それでは、CIBAの仕様をデモシナリオの流れに沿って、シーケンスと認証フローを確認しましょう。
デモのシーケンス
- <用語の補足>
Libra:Uni-ID Libraのことです。つまりOpenID ConnectにおけるOPを指します。 - AD:Authenticator Device(認証デバイス)。ユーザーがリクエストを認証・認可するデバイスです。デモシナリオでは、親が所持するスマートフォンにて、認可を行っていました。
- CD:Consumption Device(消費デバイス)。ユーザーがサービスを受けるために役立つデバイスです。POSレジや銀行窓口担当が利用するデバイスなど、ユーザー配下にあるとは限らないのが特徴です。デモシナリオでも、認可する親ではなく、子供が利用しているブラウザがCDでした。
一般的な認可コードフローでは、RPであるECサイトが、決済API実行に必要なアクセストークンを取得するため、ユーザーのエージェントをOPへリダイレクトし認可要求を行い、ユーザー自身がAPI実行を認可する。RPは取得した認可コードをアクセストークンに引き換え、決済API実行時にアクセストークンを送信する。決済API側はアクセストークンの有効性を確認し、決済処理を実行する。というような流れ(一部省略)になりますが、CIBAの場合は、AD上での認可が追加されていたり、RPからの認可要求の方法が若干異なっていたりすることがわかります。シーケンス上の各処理の詳細を以降の章でご説明します。
デモシナリオにおける各処理の解説
デモシナリオ内の各処理の内容を説明します。一連の流れをスライドショーにしています。
- <デモの流れ>
- ① 子供がRP(ECサイト)にアクセスし、親名義のクレジットカード(家族カードをイメージ)で決済を行おうとする
- ② RPは、入力されたカード番号や名義から、認証を要求するユーザーを特定する
- ③ RPは、OPに対してバックチャネルで認証要求を行う(この際に特定したユーザーに関するヒント(必須)とCD、AD双方で同一トランザクションであることを証明するためのbinding_message (任意)を送る)
- ④ OPは、受け取ったヒントをもとに、認証を要求するユーザーを特定する
- ⑤ OPは、ユーザーが特定できた時点でRPに対して受付番号(auth_req_id)を含むレスポンスを返却する
- ⑥ PRは、待機画面を返却する(binding_messageをCDの画面に表示しておく)
- ⑦ OPは、ADに対して、リクエストの承認要求を行う
- ⑧ 親は、AD上で、「同意する」の操作を行う
- ⑨ ADは、OPに対して承認結果を送る
- ⑩ OP(RP側からも可)は、ADから同意されたことを通知
※通知方法はモード選択による(後述) - ⑪ RPは、OPに対してトークンリクエストを送信する
- ⑫ OPは、RPに対してトークンレスポンスを送信する
- ⑬ PRは、取得したトークンを用いて決済API実行する
- ⑭ RPは、サービスを提供する
この中で、③と⑤と、⑩~⑫のリクエストレスポンスがCIBAの仕様で定義されています。一方で⑦のADへの通知方法などは具体的には定義されていません。講演資料では、CIBA仕様以外にも、ADへのプッシュ通知方法や、AD上でのFIDOによる認証などの実装内容を詳細に解説していますが、ここでは、CIBA仕様に関連する部分をご紹介します。
RPがユーザーを特定し認証要求を投げるまで
それでは、まず③と⑤の仕様の詳細を確認しましょう。
③では、RPは、OPがユーザーを特定するためのヒントを付与してバックチャンネルで認証リクエストを送付しています。(そのためにデモでは②でユーザーを特定するような処理を実装しています。)
下図は、Uni-ID Libraにおける③のバックチャネル認証リクエスト仕様になります。赤字で記載したリクエストパラメータうち、上の3つが、上図の③認証リクエストで記載した、ユーザーを特定するためのヒントです。
デモシナリオでは、OPは親のデバイスへPUSH通知を行っていたように、OPはユーザーがAD上でリクエストを認可できるようにする必要がありますが、どのユーザーのデバイスへ通知すればよいかわかりません。そのため、RPからユーザーを特定するための、ヒントを送る必要があります。
- login_hint_token:ユーザーを特定できる何らかのトークン(仕様は未定義)
- id_token_hint:RPが過去にOPから受け取ったIDトークン
- login_hint:ユーザーを特定できる文字列(メールアドレスやusernameなど)
その他大事なパラメータとして、binding_messageや user_codeがあります。binding_messageは、ADに通知された認証要求が確かにCD上で操作したリクエストであることを確認できるものです。CD、AD上で同じbinding_messageが表示されていることをユーザーが確認します。user_codeは、悪意のある人が、いたずらにPush通知等で認証要求を送付するのを防止するためのシークレット情報として利用することができます。
また、レスポンスでは、リクエストを識別するために作られた受付番号に相当するauth_req_id を返却します。OP、RPはこの一意の値を識別することで一連のトランザクションであることを確認することができます。
- 注:1/22に更新されたdraft3では、auth_req_idに使用可能な文字種の記載が追加されています。RPがauth_req_idを誤ってデコードしたり再エンコードする可能性を防ぐため、文字種は 'A'-'Z'、'a'-'z'、'0'-'9'、'.'、'-'、'_' に絞られています。
OPがユーザの認証デバイスへ同意を求めユーザが同意(CIBA仕様外)
講演では、ユーザーのAD(認証デバイス)へのプッシュ通知などの仕組みを説明していましたが、本記事では割愛します。詳細は講演資料をご確認ください。
RPがトークン取得し、トークンを用いて決済完了するまで
次に⑩~⑫を確認しましょう。
AD上での同意/承認結果をOPが受領した後、トークンの受け渡しが行われます。
CIBAでは、トークンリクエストとトークンレスポンスの方法として3つのモードが規定されています。これらのモードは、クライアント登録時にどのモードにするか1つのみ選択する必要があります。
どのモードで設計するのが良いかは、次章で触れたいと思います。
- AD(認証デバイス)、CD(消費デバイス)という2種のデバイスの考え方が新たに登場
- バックチャネルで認証を行うので、ユーザー特定のためのヒントをRPからOPに送信する必要がある
- CDで操作した要求と同一トランザクションであることを確認するbinding_messageという仕組みが用意されている
- ADへの通知方法はCIBA仕様では規定されていない。(本デモでは、予めOPのユーザーと紐付けておいたデバイスに対して、Firebase Cloud Messagingを使いプッシュ通知を行っています。詳細はスライドp20-21を参照して下さい)
- 認証リスエスト、トークンリクエストの紐付けとして、auth_req_idが使われる
- トークンを取得するモードは、3種類。その中から、サービスにあった適切なモードを選択する
CIBAとその周辺を実装してみた所感
今回実際にCIBAを実装してみて考慮が必要だと感じたことは以下の5点です。
- ①ヒントが複数ある点
- ②RPが認証結果を知るための3種類のモードについて、どの方式が良いのか?安全か?
- ③Security & Privacy Considerationを考慮する
- ④CIBA FAPI-プロファイルも考慮する
- 参考:(仕様外)デバイス管理も考えないといけない
- ※今回は、OPが提供するログイン用アプリという体で作成した、スマートフォン向けアプリを使い、予めコードフローなどでログインした際にユーザーとFirebaseのトークンを紐付けてOP側で管理しています。CIBAの認証リクエストが実行されたタイミングでユーザーに紐づくFirebaseトークンを利用し、スマートフォンアプリにpush通知を送っています。
以下、それぞれについて補足をしていきます。
考慮点① ヒントが複数ある点
まずは、「ヒントが複数ある」という点です。
OPを実装する以上、いずれかのヒントに対応したバックチャンネル認証エンドポイントを実装する必要があります。login_hintは、Security Considerations の章では、メールアドレスや電話番号などをヒントとしてつかう場合、プライバシー影響を考慮する必要がある と記載されています。また、login_hint_tokenは、そもそも形式が定義されていません。署名を行うこと。という記載はあります。
そうなると、形式(RPが過去受け取ったIDトークン)が明確に定義されているid_token_hintが候補に挙がります。ただし、id_token_hintはRP側の実装負荷が高いのが課題です。
RP側は、過去に通常のフローで取得したIDトークンを、ユーザーと紐付けて管理しておく。アクセスしたユーザーを何らかの手段で特定し、紐付けたIDトークンをOPに送付する。という実装を行う必要があります。
今回のデモでは、RP側はカード番号や名義人情報からユーザーを特定し、id_token_hintを送るように実装していますが、実際にはOP-RP間でどのヒントを使うのかを事前に調整しておく必要があるかと思います。
考慮点② 3種類のモードがある
続いて「トークンを取得するための3種類のモード」についてです。
今回Uni-ID Libraには3種類のモードを全て実装しましたが、Pushモードは個人的にはおすすめしません。
他の2つのモードは通常のトークンエンドポイントの拡張として、RPからのトークンリクエストに応じてOPがトークンを返却する仕組みですが、Pushモードの場合向きが逆になります。RPからのリクエスト起点ではなく、OP起点でRPに対してトークンを送りつけるという形なので、今までのトークンエンドポイント実装のベストプラクティスが通じない可能性を加味し、セキュリティ考慮が必要になります。例えば、RP側は、送りつけられたトークンが確かに同一のトランザクション(自身が発行したバックチャネル認証要求)で発行されたトークンであることを確認するような仕組み(IDトークン内にauth_req_id を追加し、検証する等)が必要になります。
次にPingモードです。こちらも一見実装が楽に見えるのですが、仕様では、“Pingモードをサポートする場合、Pollモードも実装しなければならない”という記載があります。これは、恐らくですが、OPが完了通知を送る前にRPがトークンリクエストを行った場合、結局Pollモードで定義されているエラー(authorization_pending : まだユーザによる認可が終わっていない)を返す実装が必要となるためと思われます。
であれば、最初からトークンエンドポイントに対してポーリング(RPが定期的にユーザーの認可状況を確認するリクエスト)を行うPollモードのみ実装すれば良いのではと思うのですが、RPが相当数いるようなシステムとなると、性能考慮が必要となるため、PollモードやPingモードを組み合わせて実装していく必要があると考えています。
- 注:1/22に更新されたdraft3では、”Long Polling という方式を実装しても良い”という記述が追加されました。Long Pollingとは、RPからの毎回のPollingリクエスト(例えば5秒間間隔)に応答せず、認証が完了した場合や、Long Pollingのタイムアウト時間(例えば30秒)を超えた場合に初めて応答を行うという考え方です。
考慮点③ Security & Privacy Considerationを考慮する
また、CIBAの実装をする際には当然のことながら、③Security Consideration や Privacy Consideration を考慮する必要があります。本スライドでは一部を抜粋し、Security Consideration で、RPがOPに送るhintの考慮ポイントや、逆にOPからRPの通知時の考慮事項を記載しています。また、Privacy Considerationでは、プライバシーを考慮したhintの利用について抜粋し記載しています。全量はCIBA仕様をご確認ください。
RPからヒントとしてid_token_hintが送付された場合のOPでのその検証の考え方が記載されています。例えば、IDトークン内の有効期限クレームのチェック等の標準的な検証ができない場合があります。自身が署名したIDトークンかどうかを検証する場合も、署名用の鍵をローテーションしていた場合に検証ができなくなることを考慮する必要もあります。
また、Pushモードの場合、考慮点②で記載した通り、OPから通知されたアクセストークンやリフレッシュトークンが確かに自身がリクエストした認証要求に紐づく(バインディングされている)ものであるかを確認する必要があります。そのための手段として、OPがIDトークンにauht_req_idを含め、それをRPが検証するという手順が記載されています。
その他にも、RPがCDの地理位置情報を送り、OPが送られた地理位置情報とADの地理位置情報とを照合するようなシナリオも記載されています。
CIBAでは、RPがエンドユーザーの識別子を取得する必要があるので、識別子に関するプライバシー考慮点がPrivacy Considerationの章のメインになっています。プライバシーに対する要件がある場合、login_hintの代替として、上記の3種類の識別方法が記載されています。
考慮点④ CIBA FAPI-プロファイルも考慮する
よりセキュリティ考慮が必要な金融グレードのシステム向けとして、FAPI-CIBA Profileがあります。FAPI-CIBA Profileでは、binding_massageを必須にすることや、Pushモードをサポートしないことなど、細かく要求仕様が定義されています。また、悪意のあるユーザーがいたずらに認証要求を行うことに対する対策等の仕組みなども細かく定義されています。
ここでは、すべてをご紹介は出来ませんが、主な考慮ポイントについては、下記に纏めているので、参考にしていただけたらと思います。
まとめ
CIBAは「認証すべき人と別の人がID連携を必要とし、認証すべき人が誰かを特定できる場合」に、とても有効な仕様です。これまで以上に人やモノがつながって、様々な取引が自動化されたり、サービスがシェアされる時代には、このような認証方式は欠かせないものになると考えています。
NRIセキュアでは、CIBAの仕様に準拠した認証基盤サービスの提供をはじめ、これらの技術を生かした活用事例なども引き続きご紹介していきたいと思います。
BtoCサービスに特化した顧客ID統合・管理ソリューション「Uni-ID Libra」
上述のアーキテクチャのご説明でも簡単ご紹介いたしましたが、弊社では、コンシューマーサービス向けのID管理、認証連携基盤として「Uni-ID」を2008年より提供しています。10年以上にわたる多くの大規模な認証基盤構築の経験やノウハウをパッケージとして製品化したのが、「Uni-ID Libra」です。
ご興味のある方は、下記リンクから製品情報をご覧ください。
<主な特長>
- OAuth2.0、OpenID Connect、SCIM、FIDO等の認証技術の国際標準仕様に準拠
- 認証・認可・セキュリティ設定等に必要となるパラメータも管理画面から容易に設定・変更可能
- 多要素認証や、不正アクセス検知などのセキュリティ機能や、GDPRやプライバシー保護を考慮した機能など、コンシューマーサービスの認証基盤に求められる機能を装備
- 認可機能だけ、多要素認証だけなど、必要となる機能のみ選択できるだけでなく、設定や画面のカスタマイズなど、多様なサービスに適用できる柔軟性
- 認証基盤構築やID統合の豊富な経験と、技術への知見を持つメンバーがご支援しています