🐯

OAuth/OIDCを利用するサービスで "連携を解除する" と何が行われるのか

2021/01/17に公開

ritou です。

こんな質問が来てました。

https://twitter.com/ritou/status/1350310208510148608

マシュマロだと100文字しかお返事かけないのでもうちょい書いておきます。
質問では "ログインに利用する" 前提のようですが、せっかくなのでもう少し範囲を広げて整理しましょう。

OAuth の Client が実装する必要のある機能

これは私のはてなブログの外部サービス連携の設定画面です。
Twitterと連携することで、予約投稿時やブックマークコメント時にTwitterに投稿出来たりします。

いわゆる認可フローどうこうよりも大きなレイヤーで、OAuthのClientが実装する機能としては

  • 連携
  • リソースアクセス
  • 連携解除

という3つがあります。

連携

Clientが自サービスのユーザーなどにリソースアクセスのためのクレデンシャル(トークンなど)を紐づける 機能です。

一時的にリソースアクセスを行い、そこでクレデンシャルを破棄する場合は不要でしょうが、最低限の要件としてはClient内部のユーザーとクレデンシャルを紐づけて保存します。(ここでは認可サーバー、リソースサーバー側のサービスを "Provider" と表現します。)

user_id provider credentials
12345 "Twitter" {"oauth_token":"abcde", "oauth_token_secret": "fghij"}

OAuthでProvider取得したユーザー情報に含まれるユーザーIDと、内部のユーザーIDの関係についても要件次第となりますが、一意だったり内部のユーザーIDあたり最大X個まで紐付けられると言った制約を設ける場合、ユーザーIDの紐付けも必要でしょう。

user_id provider provider_user_id credentials
12345 "Twitter" 11223344 {"oauth_token":"abcde", "oauth_token_secret": "fghij"}

先ほど掲載した画像のように "どのアカウントと紐づけられているか" をユーザー表示したいような場合はこれに加えてユーザー情報を保持する必要があるでしょう。この辺りはキャッシュしておいて良い情報なのか、頻繁に更新されるのでリアルタイムに取得し直すのかなどの判断も必要となります。

リソースアクセス

ユーザーに紐づけられたクレデンシャルを利用してリソースアクセスを実行する 機能です。

リソースアクセスと言っても

  • プロバイダの情報を取得して自サービスの機能に利用する
    • プロフィール情報、アクティビティ、ソーシャルグラフの利用など
  • プロバイダの機能をオフライン、非同期などでも利用する
    • SNSへの投稿、決済など

と言ったように分類が出来そうですが、この辺りはまた別の記事に書きます。

連携解除

OAuthのClientの場合、ユーザーに紐づけられたクレデンシャルを破棄、もしくは無効化して自サービスで想定しているリソースアクセスおよびそれに関連する機能を使えないようにする 機能であり、連携で作成した紐付けをまるっと消してしまう実装がされることが多いでしょう。
はてなアカウントの場合、この機能により、対象ユーザーはその後再度同じ、もしくは別のTwitterアカウントと連携できるようになります。

一方で、Twitter側でも同様に連携解除の機能があります。

この連携を解除すると、Twitterがはてなブログに発行済みのクレデンシャルが無効化され、リソースアクセスが出来なくなります。
しかし、当然これははてなブログ側からするとクレデンシャルが無効化されているだけであり、ユーザーの紐づけは残っています。よって、別のはてなブログのユーザーにTwitterアカウントを紐付けようとしても一意な制約がある場合は紐付け不可と判断されるでしょう。

OIDC の RP の場合

OIDC RPの場合、

  • 連携(新規登録含む)
  • プロバイダのアカウントを用いた認証
  • リソースアクセス
  • 連携解除

というふうに実装すべき機能が増えます。

OAuthの場合、最低限の要件としては内部のユーザーとクレデンシャルの紐付けとなると述べました。

自サービスのユーザーなどにリソースアクセスのためのクレデンシャル(トークンなど)を紐づける

OIDC RPの場合、ログインに利用するために内部のユーザーとプロバイダのユーザーの紐付けが必須となる場合が多い でしょう(属性情報取得のためだけにOIDCを利用する場合はそうでもありません)

連携解除の場合も、

  • プロバイダ側から連携無効化 : リソースアクセスが不可能となる
  • RP側で連携無効化 : 解除したプロバイダのユーザーによるログインが不可能になる

という違いが出てきます。

"連携解除" における、ユーザーのモチベーション

ここまでで連携解除で何が行われるかをざっくりと説明しました。

それでは、ユーザーがプロバイダ、サービスそれぞれで連携を無効化するモチベーションはどこにあるかを整理しておきましょう。

  • プロバイダ側から連携無効化
    • OAuth Client/OIDC RPのサービスを利用しなくなった、RPのサービスが終了した
    • OAuth Client/OIDC RP側で保存しているプロバイダ発行のクレデンシャルが漏洩した
    • OAuth Client/OIDC RP側でアカウントののっとりやそれに相当する障害が発生した
  • RP側から連携無効化
    • プロバイダの別のユーザーと紐付けたい
    • プロバイダ側でアカウントののっとりやそれに相当する障害が発生した

というところでしょうか。
サービス終了や別のユーザーのリソースアクセスに使いたいというの除くと、 相手のサービスで何か問題が発生したと思われる際に、自サービスに影響が及ぶのを防ぎたい というものがほとんどかもしれません。
その場合、実際はこれだけで安心とはならず、

  • ログインセッションの確認、個別の削除機能
  • 全てのログインセッションの削除機能
  • ログインの履歴、リソースアクセスや認可処理の履歴の閲覧機能

と言ったあたりも用意しておくべき機能として出てきそうです。

あわせて読んでもらいたい記事 : ユーザー認証の緊急事態に備えて提供しておきたい、セッション管理とセキュリティイベントログについて - Qiita

まとめ

  • 連携、連携解除で何が行われるかを整理した
  • OAuth Client と OIDC RP では微妙に異なる点がある。
  • 連携無効化のモチベーションについても書いた

理解の助けになれば幸いです。


本投稿も含めて、最近、OAuthの主にClient実装に関する基本的な知見をZennに書いています。

https://twitter.com/ritou/status/1349326168219025409

質問がありましたらマシュマロにて匿名にて受け付けております。

https://twitter.com/ritou/status/1350240815159808003

これまでの記事もご覧ください。

https://zenn.dev/ritou

ではまた!!!

Discussion