4

私は OpenID Connect と OAuth をいじっており、複数の OpenID プロバイダーをサポートしたいと考えています (AccountManager によって認識されているものだけではありません)。しかし、私はこの問題に遭遇しました。

インストール済みアプリケーションとして Google に対して認証する場合は、(Google によって) 事前定義されたコールバック アドレスを に渡しますhttp://localhost。そこで、次のように Google のエンドポイントにリダイレクトして OAuth フローを開始します。

String url = "https://accounts.google.com/o/oauth2/auth?scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&state=%2F&redirect_uri=http%3A%2F%2Flocalhost%3A9999&response_type=code&client_id=000000000000000.apps.googleusercontent.com";
Intent i = new Intent (Intent.ACTION_VIEW);
i.setData (Uri.parse (url));
startActivity (i);

必要に応じて redirect_uri を渡すことに注意してください (許可されているポート 9999)。次のように、このタイプのアドレスが読み込まれるのに応答するようにアプリケーションを登録しました。

<data android:scheme="http" android:host="localhost" android:port="9999" />

ただし、これにより、システムは「次でアクションを完了する」ダイアログを表示します。

ここに画像の説明を入力

そのため、電話のポート 9999 でリッスンしているものがないため、ユーザーがブラウザを選択すると、エラー ページがブラウザによって表示され、認証フロー全体が中断されます。

どうすればこれを回避できますか?

4

3 に答える 3

1

リダイレクト URL を別のスキームにするようにしてくださいapp://localhost。すべてのブラウザーがhttpおよびhttpsのハンドラーとして登録されるため、問題の一部は解決できません。ただし、リダイレクト URL に非標準のスキームを使用できる場合、問題は簡単に解決できます。独自のスキームを発明し、それを使用します (多くのアプリがそれを行いますfb://。たとえば、Facebook にはリンクがあります)。

于 2013-06-12T21:05:35.377 に答える
0

アプリに直接表示されるWebViewで認証を実行します。

これは、OAuth ページをロードする方法と、ブラウザが OAuth コールバックにリダイレクトしようとしたときに検出する方法の簡単な例です。この時点で、トークンを取得して、ログイン アクティビティまたはダイアログを閉じます。

この方法では、外部 Web ブラウザーが使用されないため、スキームまたはポートを処理するためにアプリを登録する必要はありません。

webView = findViewById(R.id.wv);
webView.setWebViewClient(new WebViewClient(){
   final String cb = "http://your_oauth_callback_uri";
   @Override
   public void onPageStarted(WebView view, String url, Bitmap favicon){
   if(url.startsWith(cb)) {
      view.stopLoading();
      Uri uri = Uri.parse(url);
      String token = uri.getQueryParameter("oauth_token");
      // TODO do whatever you need with token
   }
});
webView.loadUrl(uri);

アクティビティ、レイアウトなど、残りは作成する必要があります。

注: このコードは私の OAuth 1 アプリから取得したものですが、返された oauth_token パラメータの名前が異なる場合があることを除いて、あなたのケースでも機能するはずです。

于 2013-06-12T08:48:56.553 に答える
0

これを回避する簡単な方法はありません。Android では、特定のインテントを処理するために、あるアクティビティが別のアクティビティより優先されることは許可されていません。それは常にユーザーの選択です。この種のログイン フローには、ブラウザではなく、AccountManager または WebView を使用する必要があります (こちらを参照)。Google が、任意の URL スキームをコールバックとして使用することを禁止している唯一の OpenID プロバイダーである可能性は低いです。これには漠然としたセキュリティ上の理由がいくつか想像できます。

一般に、Android ユーザーは、AccountManager を使用することを期待しています。これは、多くの信頼できるアプリで使用されている使い慣れた UI です。それらをブラウザーに送信して機能させたとしても、技術に詳しくないユーザーの多くは、あなたが言及したようにブラウザーのクロムなどの理論的な快適さを持っていても、それを驚くべきことに気づき、とにかく心配するだろうと思います。

ブラウザを使用して本当に動作させたい場合は、ランダムなポート番号で小さな HTTP サーバーを実際に起動し、そのポートをコールバックとして使用する必要があります (インストール済みアプリの OpenID が機能する方法)。不可能ではありませんが、些細なことでもありません。

于 2013-06-14T06:54:11.493 に答える