家族ToDo(仮)開発日誌

やりたいことや行きたい場所を家族で共有するためのAndoridアプリの開発日誌(兼Android開発学習メモ)です。

開発日誌 (8) : セキュリティと利便性を両立するOAuth2.0認証シーケンス

今回の進捗

  • Web側でのOAuth2.0による認証のサンプル実装
  • セキュリティに配慮した認証シーケンスの検討

作業時間: 5h

Webアプリ(PHP)経由でOAuth

前回、Androidアプリから直接GoogleにOAuth2.0で認証しようとしたが、下記が課題だった。

  • GoogleのOAuth 2.0ではCallback URLにカスタムスキーマが使用できない(http固定)ため、コールバック時にアプリ選択ダイアログが表示されてしまいうざい(普通httpにはブラウザが割り当てられているので)
  • 毎回のGoogle認証を避けるためには端末側にアクセストークンを持たせる必要があるが、漏れたときのことを考えると頭が痛い (OpenID Connect対応していないサービスが多い現状を踏まえ)

なぜGoogleがredirect urlをhttp://localhost固定にしたのか、その理由は探し出せなかったが、前できていたのをわざわざ変更したのだから、おそらくセキュリティ的な理由*1があるからと思う。

ちなみに、もう一つのリダイレクトURLにurn:ietf:wg:oauth:2.0:oobというのがあるが、これはブラウザに表示されたPINをアプリにコピペするという方式で、これまためんどくさい。やったことあるならわかると思うが、スマホ上での文字列のコピペは大変苦労する。論外である。

参考: Using OAuth 2.0 for Installed Applications - Google Accounts Authentication and Authorization — Google Developers

とまあそんなわけで結局Androidアプリから直接OAuthするのはあきらめ、自前のWebアプリを作りそいつ側にOAuthをやらせ、Androidアプリは必要なユーザ情報だけを受け取るような感じにしようと思う。これでセキュリティと利便性を両立しようという目論見だ。

まず、ユーザ登録時。

f:id:ymkn:20140217001435p:plain

で、ユーザ登録後の認証時。

f:id:ymkn:20140217001441p:plain

ポイントは下記の通り。

利便性

  • AndroidアプリへのコールバックURLはWebアプリが発行するので、カスタムスキーマが使える (=余計なアプリ選択ダイアログは出ない)
  • もちろん、PINのコピペなど不要
  • Androidアプリ側の作りがシンプルになる

セキュリティ

  • OAuthのシーケンスはWebアプリ(jibunstyle.net)で閉じるので、Androidアプリ(KazokuToDo App)側にアクセストークンを持たせなくて良い (Webアプリに脆弱性が無い限りアクセストークンが漏洩しない)
  • Androidアプリ側にはWebアプリ側で発行した専用の認証キーだけを持たせるので、端末に保存されている情報を抜かれたとしても、OAuthに関する情報は何一つ漏洩しない。

まあ、デメリットもある。

  1. Webアプリ作らないといけない (開発工数増加)
  2. ユーザにとって良くわからんサイト(自前Webアプリ)を経由するので、怪しい
  3. 許可する対象がAndroidアプリではなく、自前のWebアプリとなっており、怪しい。
  4. 障害点が増える。自前のWebアプリが死んてたらGoogleが生きていても認証不可。

2と3はリダイレクト前にガイダンス画面(こちらは家族ToDoアプリの認証ページです。下のボタン押してGoogleのサイトに飛んだことを確認し認証を許可して下さい。)を表示することで緩和するとか。1と4は仕方が無いね。

でもまあ、2と3のデメリットを受け入れるなら、素直にWebViewを使ってAndroid端末側だけで頑張った方がいいのかね。「使ってたAndroidアプリと違うWebアプリに対して認証許可」するのがいいか、「アプリ内ブラウザでGoogleアカウントのID・パスが抜かれているかもしれない懸念を抱きながら認証許可」するのがいいか。うーん。・・セキュリティ的には前者の方がましか。

しかし、調べれば調べるほどOAuth使うとセキュリティ的に考慮しなきゃいけないところが多くて不安だな。なんか普通にユーザ登録させる機能だけにした方がよほど安全な気がしてきた。

Webアプリ側でのOAuth 2.0のサンプル実装

技術調査がてら実装してみた。時間ないので使った開発環境や技術だけ。細かいことは後日書く。

*1:OAuthのコールバック用に設定したカスタムスキーマがばれると、悪意のある他のアプリが同じカスタムスキーマを受け取れるので、アクセストークンとか盗まれてしまうから?