-
Notifications
You must be signed in to change notification settings - Fork 0
MS_PPID
-
TOP > インフラストラクチャ > 認証基盤 > クレームベース認証
- PPID
- SCIM
- SAML / WS-FED
-
Pairwise Pseudonymous Identifier (PPID)
- ある SP (Service Provider), RP (Relying Party) に対してのみ、
ある Entity の識別子として提供される値。 - 他の SP, RP には、当該 PPID を当該 Entity と関連付けることはできない。
- ある SP (Service Provider), RP (Relying Party) に対してのみ、
-
pairwise の対義語は public になる。
一般的に、結託した SP, RP による名寄せを防ぐ目的で導入される。
※ なお、PPID を渡している時に本人を特定できそうな claim を一緒に渡したら無意味。
以下のように実装しなければ、public でもそれほど問題は無さそう。
- 「userid のみを送信して認証とみなす」の様な実装をしない。
- トークンに署名する。できればクレームセットにも署名する。
-
名寄せを防止する目的(プライバシー保護)。
-
しかし、実際は、プライバシー保護で使用された事例はなく、
セキュリティを高める副作用が確認されたことはある(らしい)。- トークン置換攻撃を緩和させる副作用
- 「userid のみを送信して認証とみなす」みたいな非推奨をやってしまう
人たちのアプリのセキュリティを高めてはいる。
Pairwise Pseudonymous Identifier (PPID) の方がセキュア。
(・・・当たり前と言えば、当たり前だが。)
ウェブサービス事業者のトレンドを分析しても五分五分かなと。
| 方式 | 事業者 | 備考 |
|---|---|---|
| public | 認証ではなく認可目的のため PPID にするモチベーションは無さそう | |
| public | 昔、Pairwise だったものを OIDC 対応時に public に変更した | |
| public | Yahoo | アプリ横断の共通 ID(Yahoo ID とは異なる) |
| pairwise | Apple | Sign in with Apple |
| pairwise | - | |
| pairwise | LINE | - |
補足(最新化): Sign in with Apple は pairwise に加えて メール アドレスの中継(Hide My Email) まで提供しており、 「名寄せを防ぐ」という発想がプラットフォーム側の要件として 定着したことを示している。 また、Apple はアプリ側にも同等の選択肢を提供することを App Store の審査要件にした時期があり、 pairwise の普及を後押しした。
派生の問題。
-
別に、
sub=emailでログインしても問題はない。 -
しかし、ID 連携時の
sub = emailは、ダメっぽい。- 何故か?と言えば、
- メアドが乗っ取られると、外部ログイン経由で乗っ取られるため。
- 従って、ID 連携を行う場合は、パーマネントな ID が必要になる。
- 従って、外部ログイン時は、
-
sub=useridとするか、 - 別の方法(scope で claim を要求するなど)で userid を連携する。
-
- また、
sub = email(username)を Pairwise 化する場合、
メアドがバイナリ文字列に変更になる訳で、イロイロ実装し難い。
- 何故か?と言えば、
-
Google — public を選択している Google でも以下のように言っているらしい。
- 「Email はユニークではない可能性があり、
ユーザーを識別する主キーとしては適さない」
- 「Email はユニークではない可能性があり、
補足: OpenID Connect の仕様上も、 ユーザの一意性は
iss+subの組で判定すべきと定められている。sub単独でも、
subは IdP 内で一意なだけなので、複数 IdP を受け入れるならissと組にしないと衝突しうる「メール アドレスをユーザの主キーにする」は、 外部ログインを導入した途端にアカウント乗っ取りの経路になる。
| プロトコル | 呼称 |
|---|---|
| OIDC | Pairwise Pseudonymous Identifier (PPID) |
| SAML | Persistent Pseudonym Identifiers が PPID に該当 |
SAML でのこの実装は、
- SAML メタデータの
NameID - SAML リクエストの
NameIDPolicy
の仕様に関連する。
SAML では明示されていないが、OIDC では明示されている。
-
Client 毎にユニークになればイイ。
sub = ハッシュ関数 ( Client毎にユニークな値 || userid || salt ) -
「Client 毎にユニークな値」の要件
- 一般的には、RedirectUri や JwksUri が使用される(Client 側の検証可能な URI)。
- ClientID は、削除・追加で変わり、変更後、重複しているケースもある。
- RedirectURI は
- ドメイン保持すれば変更されない
(が、EndPoint までか?FQDN までか?など悩ましい問題も) - CIBA(
MS_CIBA.md)は RedirectUri が無いので JwksUri とか言うが、
FAPI では JwksUri を使わないなど。
- ドメイン保持すれば変更されない
-
salt が必要になる理由
「Client 毎にユニークな値」が漏れ得る場合(ClientID、RedirectUri)、
前述の計算方法が解れば、PPID 間の紐付けが可能になるタメ。
補足: OpenID Connect Core の仕様では、 pairwise の
subは sector identifier を用いて算出すると定められている。sub = Hash( sector_identifier || local_account_id || salt )sector identifier は既定では RedirectUri のホスト部で、
sector_identifier_uriを登録すれば 複数の RedirectUri を持つクライアント群で同じsubを共有できる。 「ClientID に統一する」という後述の判断は、 仕様の推奨からは外れるが、CIBA を扱う都合を優先した設計判断である。
-
以下の計算式を使用する。
sub = ハッシュ関数 ( Client毎にユニークな値 || userid || salt ) -
ハッシュ関数: SHA-256
-
Client 毎にユニークな値
- OIDC — ClientID に統一する(CIBA には RedirectUri が無いので)
- SAML —
samlp:AuthnRequestの Issuer を利用する。
汎用認証サイトは OAuth/OIDC メインなので、結局、
samlp:AuthnRequestの Issuer に ClientID を使っている。
備忘録。
・・・と言うことで、
-
/userinfoでは、sub以外の値を返さない。 - そもそも、IdP 側が、PPID で
sub(user) を特定できないので。
- Client 認証とは、
- Client Credentials グラント種別
- JWT bearer token authorization グラント種別
- Client に名寄せは無いダロと。
sub(user) を特定できないので、
- User Store を参照できないので、
- User Resource を参照できない。
-
PPID は、
- 認証用の Client に適用し、
- Resource アクセス用の Client には適用しない。
-
ただし、認証用の Client も、
- フェデレーションする必要はあるし、
- フェデレーション・スタイルを決定する必要もある。
- PPID でも、紐付けに必要な、ユーザ名やメアド程度は
取れるように実装する必要があるケースは多そう。
-
SP のログインに ID 連携は必須ではないと言う感じ。
- IdP/STS から、
- 取得したトークン検証が済めばログインするなど。
- 取得したユーザ名やメアドを、そのまま使う。
- PPID で、ユーザ名やメアドが取れない場合は、
ローカル・ログインの機能を実装し、
ローカルのログイン・アカウントと外部アカウントを紐付ける
(となると、ローカルのログインの実装が必要になる)。
- IdP/STS から、
-
IdP/STS との関係次第
- 関係が密であれば、ID 連携は不要。
- トークン検証が済めばログインするなど。
- そもそも、PPID も不要で、ユーザ名やメアドが取得できるハズ。
- 関係が疎であれば、ID 連携をする。
- トークン検証後、ローカルの userid と、連携先の userid or ppid を紐付ける。
- 若しくは、関係が密になるように、自前の IdP を建てて、Hybrid-IdP する。
- 前者は、アプリでやるには面倒なので、やるなら、後者が良さそうではある。
- 関係が密であれば、ID 連携は不要。
-
Owin.Security ライブラリを使用した外部ログインに関しては、
ASP.NET Identity の補助輪パワーで
一応、適切に実装が出来てるっポイ。
UserLoginInfoがLoginProviderとProviderKeyを含んでいる。 -
フェデレーション・スタイルに関する考察。
- 著名ウェブサービス事業者の場合
(これは ≒ 外部ログイン、ソーシャル・ログインの実装)- トークン検証後、
-
UserLoginInfo(IdP 名+userid or ppid)を永続化して記憶し、 - ローカル・アカウントとは、メアド一致で紐付けている
(異なるメアド同士のアカウントを紐付けるのもなんかアレなので)。
- 関係が疎 or フリーメール可能な IdP との場合は、前述と同じ。
- 関係が密 or 企業メールが前提な IdP との場合
(これは ≒ ID フェデレーションの実装)- トークン検証後、
-
UserLoginInfo(IdP 名+userid or ppid)を永続化して記憶し、 - そのまま、ログイン・アカウントと紐付けなどでも良い。
- また、アカウント同期の方式なども検討しておく必要がある
(特に、PPID を採用するようなケースでは、別で同期を行う必要がある)。
- 著名ウェブサービス事業者の場合
補足(セキュリティ): 「メアド一致で自動的に紐付ける」は 実装として一般的だが、未検証のメール アドレスで行うと アカウント乗っ取りになる(pre-account-hijacking)。
- IdP から受け取る
email_verifiedを必ず確認するemail_verifiedが false、または claim 自体が無い IdP は信用しない- 自動紐付けではなく、既存アカウントへのサインインを求めて明示的に連結させる
SCIM のようなプロビジョニング連携がある環境なら、 そもそもメアド突合に頼らずに済む。
- クレームベース認証
- 認証基盤
- トークン
- 各社のログインAPIで返ってくるIDは何であるのかと、PPIDの現状について - Gist
- OpenID Connect Core 1.0(日本語訳)
- OpenIDでPPIDの実装方法を確認した。 - r-weblife
- 某ペイの件でPPIDが話題になっていたので調べてみた。 - 開発基盤部会 Blog
Tags: IT国際標準, 認証基盤, クレームベース認証
このWikiは「Open棟梁Project」,「OSSコンソーシアム 開発基盤部会」によって運営されています。