去る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月時点のものです。最新の仕様とは異なる可能性があります。
Open ID Connect CIBAの中身を説明する前に、まずは「CIBA」の考え方を整理したいと思います。
OpenID Connect Coreでは、認可、認証の代表的なプロセスとして、認可コードフローが定義されています。しかし、「サービスを利用」するユーザー自身が「認証/認可」を行う流れが一般的で、多様なデバイス(例えば、スマートスピーカーやIoT、POSなど)への対応や、第三者がユーザーの同意に基づいてAPIを実行できるような仕様にはなっていませんでした。
そこで、「サービス利用」と「認証/認可」を行うデバイス・ユーザーを分離したいというユースケースを実現するために生まれた考え方が「CIBA」です。
例えば、下記のように、決済や認証のデバイスが多岐にわたる場合や、ユーザーと実行する人が、別の人物である場合などに有効です。
講演当日は、「子の(親のカードを使った)支払いを親がスマートフォンで承認したい」のデモを実装し、解説しました。デモの流れを簡単に説明すると、以下の通りになります。
当日行ったデモのイメージは以下の動画をご参照下さい。
画面の左側が、子が操作するブラウザ(後述のConsumption Device)、右側が、親が操作するスマホ(後述の Authentication Device )の画面をミラーリングしたものになります。
なお、デモにあるFIDO UAFによる生体認証の処理は、Uni-ID Libraのオプションで実行できる処理で、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サイトを実装しました。
それでは、CIBAの仕様をデモシナリオの流れに沿って、シーケンスと認証フローを確認しましょう。
一般的な認可コードフローでは、RPであるECサイトが、決済API実行に必要なアクセストークンを取得するため、ユーザーのエージェントをOPへリダイレクトし認可要求を行い、ユーザー自身がAPI実行を認可する。RPは取得した認可コードをアクセストークンに引き換え、決済API実行時にアクセストークンを送信する。決済API側はアクセストークンの有効性を確認し、決済処理を実行する。というような流れ(一部省略)になりますが、CIBAの場合は、AD上での認可が追加されていたり、RPからの認可要求の方法が若干異なっていたりすることがわかります。シーケンス上の各処理の詳細を以降の章でご説明します。
デモシナリオ内の各処理の内容を説明します。一連の流れをスライドショーにしています。
この中で、③と⑤と、⑩~⑫のリクエストレスポンスがCIBAの仕様で定義されています。一方で⑦のADへの通知方法などは具体的には定義されていません。講演資料では、CIBA仕様以外にも、ADへのプッシュ通知方法や、AD上でのFIDOによる認証などの実装内容を詳細に解説していますが、ここでは、CIBA仕様に関連する部分をご紹介します。
それでは、まず③と⑤の仕様の詳細を確認しましょう。
③では、RPは、OPがユーザーを特定するためのヒントを付与してバックチャンネルで認証リクエストを送付しています。(そのためにデモでは②でユーザーを特定するような処理を実装しています。)
下図は、Uni-ID Libraにおける③のバックチャネル認証リクエスト仕様になります。赤字で記載したリクエストパラメータうち、上の3つが、上図の③認証リクエストで記載した、ユーザーを特定するためのヒントです。
デモシナリオでは、OPは親のデバイスへPUSH通知を行っていたように、OPはユーザーがAD上でリクエストを認可できるようにする必要がありますが、どのユーザーのデバイスへ通知すればよいかわかりません。そのため、RPからユーザーを特定するための、ヒントを送る必要があります。
その他大事なパラメータとして、binding_messageや user_codeがあります。binding_messageは、ADに通知された認証要求が確かにCD上で操作したリクエストであることを確認できるものです。CD、AD上で同じbinding_messageが表示されていることをユーザーが確認します。user_codeは、悪意のある人が、いたずらにPush通知等で認証要求を送付するのを防止するためのシークレット情報として利用することができます。
また、レスポンスでは、リクエストを識別するために作られた受付番号に相当するauth_req_id を返却します。OP、RPはこの一意の値を識別することで一連のトランザクションであることを確認することができます。
講演では、ユーザーのAD(認証デバイス)へのプッシュ通知などの仕組みを説明していましたが、本記事では割愛します。詳細は講演資料をご確認ください。
次に⑩~⑫を確認しましょう。
AD上での同意/承認結果をOPが受領した後、トークンの受け渡しが行われます。
CIBAでは、トークンリクエストとトークンレスポンスの方法として3つのモードが規定されています。これらのモードは、クライアント登録時にどのモードにするか1つのみ選択する必要があります。
どのモードで設計するのが良いかは、次章で触れたいと思います。
今回実際にCIBAを実装してみて考慮が必要だと感じたことは以下の5点です。
以下、それぞれについて補足をしていきます。
まずは、「ヒントが複数ある」という点です。
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種類のモード」についてです。
今回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モードを組み合わせて実装していく必要があると考えています。
また、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種類の識別方法が記載されています。
よりセキュリティ考慮が必要な金融グレードのシステム向けとして、FAPI-CIBA Profileがあります。FAPI-CIBA Profileでは、binding_massageを必須にすることや、Pushモードをサポートしないことなど、細かく要求仕様が定義されています。また、悪意のあるユーザーがいたずらに認証要求を行うことに対する対策等の仕組みなども細かく定義されています。
ここでは、すべてをご紹介は出来ませんが、主な考慮ポイントについては、下記に纏めているので、参考にしていただけたらと思います。
CIBAは「認証すべき人と別の人がID連携を必要とし、認証すべき人が誰かを特定できる場合」に、とても有効な仕様です。これまで以上に人やモノがつながって、様々な取引が自動化されたり、サービスがシェアされる時代には、このような認証方式は欠かせないものになると考えています。
NRIセキュアでは、CIBAの仕様に準拠した認証基盤サービスの提供をはじめ、これらの技術を生かした活用事例なども引き続きご紹介していきたいと思います。
上述のアーキテクチャのご説明でも簡単ご紹介いたしましたが、弊社では、コンシューマーサービス向けのID管理、認証連携基盤として「Uni-ID」を2008年より提供しています。10年以上にわたる多くの大規模な認証基盤構築の経験やノウハウをパッケージとして製品化したのが、「Uni-ID Libra」です。
ご興味のある方は、下記リンクから製品情報をご覧ください。
<主な特長>