ユーザーによるOAuthのScope選択について

こんにちは、ritouです。

急に寒くなってきましたが、いかがお過ごしでしょうか?

最近、Android Appのインストール時のPermissionが話題になったりしてます。
その話になると、OAuthの同意画面も同じじゃないかとかも言われます。

OAuthにおける同意内容というのは「Clientがあなたの○○にアクセスする権限を要求しています」というものですが、これは主にscopeパラメータで管理されています。

書いた後で気づいていたのですが、以前もこのあたりの話についてエントリを書いたことがありました。
OAuthのScopeはどうあるべきか? - r-weblife

今回は今一度、「OAuthのScopeをユーザーが選択するようにしたらどうなるのか」について考えたことを書いておきます。

実際のAuthZ ServerはScopeについてどう実装しているの?

Facebook, Google, mixi, ...だいたいのAuthZ ServerはClientから要求されたScopeにひもづくリソースへのアクセスを許可するかどうかをユーザーにゆだねます。
それらは、Allow or Denyの二択です。

私が思うに、の前に、OAuth 2.0の仕様を確認しましょう。

仕様はどうなっているの?

みんな大好きOAuth 2.0において、
AuthZ Request(同意画面にリダイレクトさせるリクエスト)と、
同意画面のあとにAuthZ CodeやAccess Tokenを返すAuthZ Responseというものがあります。
それらはどちらもscopeパラメーターを含むことができます。

ここで、「AuthZ ServerはClientから要求された全てのScopeに対しユーザーの同意を得たあと、同じパラメータ文字列をResponseに含まなければならない(MUST)」などという仕様はありません。
AuthZ Serverは自らのポリシーやClientの特性に応じてScopeの範囲を狭めることもできます。
ユーザーの意志によってScopeの範囲を狭めることも特に問題はありません。
では、なぜそうそうたるAuthZ Server達はこれを実装しないのか?

なんでやらないの?

ここから私の想像になります。
一般的に、登場人物はAuthZ Server, User, Clientの3者なので、そのあたりを意識しながら進めます。

AuthZ Server : やろうと思えばできるけど、、、

AuthZ Serverとしては、実装自体は特に難しい話ではないと思います。
同意画面にチェックボックスつけて、選択した値を受け取り、レスポンスやその後に使うために保存しておくScope文字列を絞るとか。

AuthZ Serverができるならもうそれで解決・・・でしょうか?
ここで、いくつか気になる点があります。
「Clientって、要求してきた全てのScopeが使えないと、サービスとして成り立たないのではないのか?」
「UserにScopeを選択させるUIについて、はたしてユーザーが直感的に操作できるのだろうか?」
など。

Client : 選択させるのはいいけど、Scope不足でサービスが成り立たないのは勘弁してほしい

例えば、「複数のSNSの情報を取得し、マルチポストができます」とうたうアプリに投稿のScopeが渡されなかったらどうなってしまうでしょうか。
READ ONLY?そんなアプリ使えないですね。

先ほどの仕様のところで説明するの忘れましたが、OAuthのScopeについて、Clientが"必須"かどうかを指定するパラメータが無いのです。

この後画面を紹介するOpenID AXでは、"この属性をください"+"必ずください"パラメータが存在します。
最近では、OpenID ConnectのRequest Objectでは、要求するUserInfo Claimsのそれぞれについてoptionalかどうかを指定できます。

OAuthでこの必須指定パラメータの課題をクリアするためには、次のような対策が必要でしょう。

  • (A) AuthZ Serverがユーザーに全てのScopeのON/OFFを制御させたとしても、Clientが返されたScopeを検証して正しくエラーハンドリングする
  • (B) 拡張仕様として"オプションScopeパラメータ"を追加し、それらで指定された値をチェックボックスで制御する

という感じでしょうか。

AはClientだけで実現可能です。というか今の仕様でもやらないとダメなのですが。
Clientがサービスを提供するために必須であるScopeがAuthZ Responseに含まれなかった場合、「このアプリではあなたのタイムラインの内容を取得する権限、タイムラインに書き込む権限を必要としています。」
のようなエラー文言を出すなどという対応が必要です。

もう少し厳密にやるのであれば、Bの形式かなと思います。
現在、このようなオプションScopeパラメータを利用する拡張は存在しません。私が今考えただけです。
追加パラメータで指定する内容が"必須Scope"ではなく"オプションのScope"とした理由は、現行の仕様のまま実装したClientに影響させないためです。まぁ、世の中のClientがAのようなScopeのハンドリングをちゃんとしていればいいのですが。
で、オプションScopeパラメータを指定することで、「タイムライン、プロフィールは必須、メッセージのやりとりは任意」といった要求が可能になります。
Server側ではタイムライン、プロフィールの項目はチェックボックスを外せない状態、メッセージのやりとりについてはチェックボックスを外せる状態にすることでうまくいきそうな気がします。

あとはユーザーに見せるUIだけですね。

User : 渡される情報をコントロールできる方がいいけど、もちろん使い易さも大事

「ユーザーに理解してもらいやすい、使いやすいUI」
これはなんとかすればなんとかなる話なのではないかと。

世の中のユーザーさん達のリテラシーの高まりも感じる今、
ユーザーが自分で渡される情報をコントロールできる世界が求められています。

とはいえ、現状はまだまだOAuthやOpenIDの同意画面の内容については業界全体で改善が必要かもしれません。ある程度実装しているところが増えた今、このあたりのUI、UXについての勉強会とかもできるといいですね。

OpenID AXでは同じようなことが実装されている

AXっていうのは属性情報のやりとりのための拡張仕様ですね。
みなさん、覚えていますか?これも似たような話です。

Y!JのAXの画面を見てみましょう。

チェックボックスついてますね〜。これで渡す情報をコントロールできますね〜。
ユーザーがチェック外した場合、OPは「ごめん、本名渡したくないらしい。理由は知らんけど。まぁ、そんなに知りたいなら直接ユーザーに聞けや!」ということになっているわけですね。

まぁ、属性が足りないからと言ってサービスが成り立たなくなるようなことは少ないと思いますし工夫できるという点で、OAuthのScopeとは話が違いますね。

まとめ

  • Server側の実現は可能
  • Client側はAuthZ Response内のscopeパラメータの値があるとき、ちゃんとハンドリングをすべき
  • 拡張仕様でオプションScopeパラメータを追加するのもいいかも

さて、今後の各Serverの実装に注目していきましょう。
ではまた!