こんにちは、富士榮です。
厳密にはOpenID Connectの仕様に定義されていませんが、以前実装したPairwise識別子(PPID)に加えて匿名の識別子(Transient Identifier)をサポートしたくなるシーンが存在するので、対応を入れていきたいと思います。
その前にこれまでのおさらいです。
- まずは全体像から
- まずOpenID Providerの情報をRelying Partyに提供する
- OpenID Providerを作る)認可エンドポイントを作る
- OpenID Providerを作る)トークンエンドポイントを作る
- OpenID Providerを作る)UserInfoエンドポイントを作る
- OpenID Providerを作る)response_typeを実装する
- OpenID Providerを作る)Hybridフローを実装する
- OpenID Providerを作る)Pairwise識別子を実装する
- OpenID Providerを作る)scopeの定義と返却する属性
- OpenID Providerを作る)定義済み属性の値として何を返却すべきか
- OpenID Providerを作る)トークンエンドポイントにクライアント認証を実装する
- OpenID Providerを作る)認可エンドポイントでクライアントの登録状態を検証する
- OpenID Providerを作る)ユーザ情報をデータベースから取得する
- OpenID Providerを作る)login_hintを使ってログインユーザを指定する
識別子の種別、および仮名と匿名の違い
識別子は主体を一意に特定するために利用される属性(群)を表しますが、名寄せのリスクなどに応じてどのような値を返すべきかについて十分な考慮が必要です。
そもそも識別子には公開、仮名(かめい)、匿名の3種類が存在します。
上記の表に示した通り、全てのRPに対して同じ識別子の値を送出するpublicなタイプ、同一のRPに対しては毎回同じ値を送出するPairwiseがOpenID Connectにおいては定義されています。ただし、特定のケースにおいて同一識別子出会ったとしても毎回送出する識別子を別のものに変えたい、というケースも存在します。SAMLにおいてはこのケースを想定してnameid-formatとしてpersistent(いわゆる仮名であるPairwise)に加えてtransient(匿名)を定義していました。
ここで仮名と匿名の違いを正しく理解しておきましょう。
- 仮名:連続性がある。つまり外野から見ると誰だか分からないが、特定のRPから見ると一意に主体を識別できる
- 匿名:連続性がない。外野から見ても特定のRPから見ても一意に主体を識別することができない
この辺りはかなり昔にイベントでしゃべった資料が出てきたので貼り付けておきます。
ID連携における仮名 from Naohiro Fujie
実装してみる
前置きが長くなりましたが、実装してみましょう。
基本的にはpairwiseの中の種別として実装をしてみたいと思いますので、設定ファイルにスイッチを作っておき、指定されたオプションによって仮名か匿名かを決めていきたいと思います。
.envに識別子のタイプを指定できるようにします。
# 識別子の種別:PERSISTENT or TRANSIENT
IDENTIFIER_TYPE=TRANSIENT
次に識別子を生成するところのロジックを分岐させます。
oauth2/oauth.js
// 識別子タイプの判定(Persistent or Transient)
let PPID;
switch(process.env.IDENTIFIER_TYPE){
case "TRANSIENT":
// 魔界異なる識別子を生成する
PPID = crypto.randomUUID();
break;
case "PERSISTENT":
default:
// Pairwise識別子の生成
PPID = utils.createPPID(payload.local_identifier, req.query.redirect_uri);
}
以上で完成です。
初回アクセスでの識別子(sub)の値
同じRPへのアクセスですがsubの値が変わっていることがわかります。
今回のコードを含めこちらに挙げてありますので参考にしてみてください。
0 件のコメント:
コメントを投稿