ここ数日、OAuth の実装を立ち上げて実行してきました。Android ではなく、OAuth で保護されたサービスへのプロキシとして機能する Web サーバーで。私は Android クライアントを実装しようとしていますが、私の頭はまだセキュリティと実装の問題に悩まされています。
クライアントが単なる Web ブラウザーである場合、OAuth は非常に面倒です。次の一連の手順があります。
- (クライアント Web ブラウザ) プロキシ サーバーにリクエストを送信
- (プロキシ サーバー) OAuth プロバイダーからの無許可のトークンを要求する (例 - Web サービス API)
- (プロキシ サーバー) OAuth プロバイダーにユーザーにトークンの承認を依頼します。Web ブラウザーを OAuth プロバイダーの「承認」URI にリダイレクトする
- (OAuth プロバイダー) ユーザーが承認を完了した後、ブラウザーをコールバック URI にリダイレクトします。
- (プロキシ サーバー::コールバック URI) 認証トークンをアクセス トークンと交換し、今後の呼び出しのために保存します
- OAuth プロバイダーへの API 呼び出しを行い、クライアントの Web ブラウザーに応答ドキュメントを返します
もう、このままで十分です。しかし、クライアントとしてモバイル アプリで同じメカニズムを使用すると、さらに複雑になります。もちろん、問題は、OAuth ダンスを実行しているときに、モバイル アプリのコード フローにブラウザー セッションを挿入するためにいくつかのアクロバットを行わなければならないことです。これは、次のように OAuth ダンスをさらに複雑にする必要があることを意味します (この例では、物事を具体的にするために Android アプリを使用しています)。
- (モバイル Web アプリ::ネイティブ コード) Java/HTTP を使用してプロキシ サーバーからリクエストを行う
- (プロキシ サーバー) OAuth プロバイダーからの無許可のトークンを要求する (例 - Web サービス API)
- (プロキシ サーバー) OAuth プロバイダーによるユーザー認証用のリダイレクト URI を含む応答ドキュメントをモバイル Web アプリに返します。
- (モバイル Web アプリ) インテント フィルターがインストールされた認証 URL で Web ブラウザー アクティビティを起動します。ただし、プロキシ サーバーの指定されたコールバック URI を格納してから、インテント フィルターで URI を簡単に識別できるように作成された特別な「偽の」URI に置き換えます (次の手順を参照)。
- (OAuth プロバイダー) ユーザーが承認を完了した後、ブラウザーを「偽の」コールバック URI にリダイレクトします。
- (モバイル Web アプリ) インテント フィルターは「偽の」コールバック URI を検出し、そのシグナルを使用して制御を取り戻します。プロキシ サーバーのコールバック URI を再構築し、Java/HTTP を使用して要求を実行します。
- (プロキシ サーバー::コールバック URI) 認証トークンをアクセス トークンと交換し、以前のように将来の呼び出しのために保存します。
- OAuth プロバイダーに対して API 呼び出しを行い、応答ドキュメントをモバイル Web アプリに返す
ご覧のとおり、これはかなり恐ろしいものです。これを行うためのもっと簡単な方法があれば、私はそれを聞きたいと思っています. 私が知る限り、他に 2 つの選択肢しかなく、それぞれに重大な問題があります。
1) プロキシ サーバーのことは忘れて、モバイル Web アプリからすべてを直接実行します。ここでの大きなセキュリティ ホールは、OAuth コンシューマ キーとシークレットをアプリに「焼き付ける」必要があることです。攻撃者がコードを逆コンパイルしてそれらの文字列を探し出すと、リバース エンジニアリングの経験がある人にとってはかなり簡単な操作ですが、アプリケーションとユーザーに大混乱をもたらす可能性があります。
2) ユーザーがログイン名とパスワードを提供する XAuth に切り替えます。ユーザーは、それらを保存せず、XAuth サーバーとのアクセス トークンと直接交換することに「同意」します。最初の問題は、その情報を提供するユーザーの信頼を獲得することです。OAuth はこの問題を解決するために作成されました。もちろん、ログインの詳細を破棄するという約束を守らない人々はどうなるでしょうか? さらに悪いことに、XAuth サーバーは XAuth をサポートし、HTTPS (SSL) 接続を提供する必要があります。私は、どちらもサポートしていない Web API を数多く見てきました。もちろん、SSL 接続は必要です。これがないと、XAuth 要求を行うときにユーザーのログイン名とパスワードをプレーン テキストで送信することになります。
http://blog.zyber17.com/post/1283741364/why-xauth-is-a-really-dumb-idea
参考までに、プロキシ サーバーは使用しませんが、次の例は、モバイル アプリの OAuth インタラクションにブラウザー セッションを挿入し、コールバック URI をインターセプトするための上記の手法を示しています。
http://blog.doityourselfandroid.com/2010/11/10/oauth-flow-in-android-app/
したがって、どう見てもかなり醜いように見えますが、プロキシ Web サーバーに保存されているアクセス トークンを適切に検索できるように、ユーザーの独自のユーザー ID を作成して管理するという追加の煩わしさにも触れませんでした (ユーザーが管理するための PIN またはアクセス コードがもう 1 つ必要な煩わしさ)。
興味深い補足: Android Web ブラウザー セッションのセキュリティについて調査したところ、現在の Web ページ HTML へのアクセスが許可されていないことがわかりました。アクセスできれば、悪意のある Android コーダーがユーザーのログインとパスワードを簡単に盗み出し、OAuth の目的と意図を完全に無効にすることができます。CacheManager オブジェクトを介してその HTML を取得する方法があるかもしれないことを知ってがっかりしました。不思議なことに、そのオブジェクトは現在非推奨であり、Android のドキュメントに従って削除される予定です。これは、Google が (潜在的な) セキュリティ ホールを発見し、次のビルドでそれを削除するための措置を講じていることを意味します。
http://developer.android.com/reference/android/webkit/CacheManager.html
最後に、OAuth アプリケーションを作成する際にこれらとまったく同じ問題に苦しんでいる人々の考えを聞きたいと思います。
-- ロシュラー