web-dev-qa-db-ja.com

OWINのGetExternalLoginInfoAsyncは常にnullを返します

新しいMVC5 Webアプリケーションを作成しました。GoogleまたはFacebookでログインしようとすると、ExternalLoginCallbackAccountControllerアクションが呼び出されますが、GetExternalLoginInfoAsync()は常に返されますヌル:

var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
    return RedirectToAction("Login");
}

常にnullであるため、ログインページにリダイレクトされ、プロセスが最初からやり直されます。どうすれば修正できますか?

67
VineetYadav

OWINのGoogleログインを取得して、標準のVisual Studio 2013、ASP.Net MVC5サイトで適切に機能させるには、次のことを行う必要がありました。

  1. https://console.developers.google.com/project でGoogle OpenIdアカウントを設定します

  2. コールバックURLを_blah/signin-google_に設定します。
    あなたがしてはいけないことに関する重要な注意事項

    • GoogleにHTTPSを使用してリダイレクトする必要はありません。プレーンな http:// localhost にリダイレクトすることもできます。問題ありません。

    • リダイレクトURLに何も設定する必要はありません-Web.Configにルート、コントローラーアクション、または特別なアクセス許可はありません。リダイレクトURLは常に/ signin-googleであり、OWINはこれをバックグラウンドで処理します。

例として、サイトがme.comの場合、Google Developer Consoleに次の3つのコールバックURLがあります。

_http://localhost:53859/signin-google
http://test.me.com/signin-google
https://me.com/signin-google
_

VSがプロジェクトに提供したポート番号を含む最初のもの。

  1. Google+ APIを有効にします。これは落とし穴の隠れたb ****の1つであり、ここでの質問の問題の根本的な原因です。これを行わないと、_/account/ExternalLoginCallback_へのリクエストに_&error=access_denied_。これは、OWINがユーザーのGoogle+基本プロファイルに対して行った許可要求に対してGoogleがノーと言ったためです。これが誰のせいなのか、GoogleとMicrosoftのどちらが原因なのかわかりません。

デベロッパーコンソールでGoogle+ APIを有効にするには、左側の[API]をクリックし、Google +を探してクリックし、[有効にする]をクリックします。はい、本当にそうする必要があります。 そうしないとうんざりです

  1. GoogleがDevelopers Consoleで提供したClientIdとClientSecretをStartup.Authに追加しますが、OAuth2を明示的に使用し、ユーザーのメールアドレスを明示的に要求するようにプロセスのコードを改善します。

    _var google = new GoogleOAuth2AuthenticationOptions()
    {
        ClientId = "123abc.apps.googleusercontent.com",
        ClientSecret = "456xyz",
        Provider = new GoogleOAuth2AuthenticationProvider()
    };
    google.Scope.Add("email");
    app.UseGoogleAuthentication(google);
    _

それでおしまい。それがついに機能しました。

もう一度繰り返しますが、OWIN/Googleが機能しておらず、現在のVS2013/MVC5/OWINテンプレートではほとんどすべてが間違っているという点で、これに関する多くの回答があります。
Web.Configを変更する必要はまったくありません。
特別なルートを作成する必要はありません。
_/signin-google_を別の場所にポイントしたり、別のコールバックURLを使用したりしないでください。また、_/account/externallogincallback_またはexternalloginconfirmationに直接結び付けないでください。 _/signin-google_とOWIN/Googleプロセスで必要な手順の両方が異なります。

101
Chris Moschini

OK、なぜnullなのかがわかりました。 GoogleコンソールでGoogle + APIを有効にする必要があります。また、秘密鍵をコードに貼り付けた後、秘密鍵が最後にスペースで連結されていないことを確認してください。なぜ通常のエラーを返せないのですか?知りません。

46
Ronen Festinger

NugetパッケージMicrosoft.Owin.Security.Facebookバージョン3.0.1はFacebook Loginで動作しなくなったようです。

このパッケージをプレリリース3.1.0バージョンに更新すると、次を使用できます。

インストールパッケージMicrosoft.Owin.Security.Facebook -Pre

19
Luke

他の人が正しく言及したように、ほとんどの場合、あなたはGoogle+ APIへの許可を持っていないため、Google API Managerのプロジェクトの許可をGoogle+ APIに取得する方法は次のとおりです

ステップ1。上部のコンボボックスからプロジェクトを選択し、ダッシュボード> APIを有効にする enter image description here

ステップ2:Google plusを検索して選択 enter image description here

ステップ3:有効にします! enter image description here

そのプロジェクトのダッシュボードに戻ると、そのプロジェクトの有効なAPIのリストが下部に表示されます enter image description here

これは私の問題を解決しました:

Google+ APIを有効にします。これは落とし穴であり、ここでの質問の問題の根本的な原因です。これを行わないと、/account/ExternalLoginCallbackへのリクエストに&error=access_deniedが含まれていることを簡単に見逃してしまいます。 OWINがユーザーのGoogle+基本プロファイル用に作成した許可要求に対していいえ。これが誰のせいなのか、GoogleとMicrosoftのどちらなのかわかりません。

デベロッパーコンソールでGoogle+ APIを有効にするには、左側の[API]をクリックし、Google +を探してクリックし、[有効にする]をクリックします。

3
Hugh Proctor

私はそれがばかげていることを知っていますが、長い闘争の後、IISを再起動すると問題が解決しました。

3
Omri

アプリケーション内のすべてのナゲットパッケージを更新するだけで機能するようになり、機能しました。

Web Apiでこの問題が発生している人向け。他の解決策は、Google Plus APIが有効になっていてもAuthenticationManager.GetExternalLoginInfoAsync();が常にnullを返すのを助けません。

このカスタム関数を使用してlogininfoを取得します。明らかに、MicrosoftはWeb API経由でリクエストするときにGetExternalLoginInfoAsyncのバグを持っています。

private async Task<ExternalLoginInfo> AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer()
        {
            ExternalLoginInfo loginInfo = null;

            var result = await Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer);

            if (result != null && result.Identity != null)
            {
                var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier);
                if (idClaim != null)
                {
                    loginInfo = new ExternalLoginInfo()
                    {
                        DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""),
                        Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value)
                    };
                }
            }
            return loginInfo;
        }
1
batmaci

今日この問題に出くわし、プロバイダーを割り当てた後にリモートCookieを定義したことがわかりました。

必ず配置してください...

app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

前...

app.UseFacebookAuthentication(
                   appId: "",
                   appSecret: "");
1
Hagge

私はそれを機能させるために次のことをしました。

開発者ポータルにログオンし、アプリケーションを見つけて以下を実行します。

アプリの詳細>アプリ中心のリストプラットフォーム> Webサイトで[はい]を選択します

1
tony

私にとっては、古い移行ですが、.NET 4.6.1 MVC Webサイトをコア1.1に移行していました。動作する前に作業が停止し、バックアップを選択すると、2.xに移行していました。

私の問題は、Googleからのコールバックが私のサイトからの_404_に遭遇したことでした。 _AccountController.ExternalLoginCallback_をヒットするはずだと思ったので、それに[Route(...)]を追加し、Googleのコールバックがアクションをヒットしたことを確認しました。

次に、この行で返されたnullをヒットします(どのようなマニアがnullを返しますか?)

_var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync();
_

私はそれをリバースエンジニアリングし、最終的にExternalSchemeのハンドラーを取得するようにしました。

それはすべて間違っているように見え、ミドルウェアはコールバックURIをインターセプトするだけであると感じたため、[Route(...)]を削除し、_404_の問題が戻ってきました。

その後、起動時にこれを追加する必要があることがわかりました。

_applicationBuilder.UseAuthentication();
_

これにより_404_は解決されますが、別の問題が発生します。

AuthenticationSchemeが指定されておらず、DefaultSignInSchemeが見つかりませんでした。

ここにデフォルトのスキームを追加することにより、上記のエラーを解決します。

_serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme)
    .AddGoogle(googleOptions => Configuration.Bind("OAuth2:Providers:Google", googleOptions))
    .AddExternalCookie();
_

これで_AccountController.ExternalLoginCallback_が何らかの魔法によって再び呼び出されますが、null戻り値に戻ります。

このコードを問題のある行の上に追加しました。これは基本的に内部で行われていることです(GitHubでMicrosoftのコードを見て)。興味深いことに、hCookieAuthenticationHandler型であり、aにはGoogleからの私の主張と情報がすべて含まれています!

_var authHandler = this.HttpContext.RequestServices.GetRequiredService<IAuthenticationHandlerProvider>();
var h = await authHandler.GetHandlerAsync(this.HttpContext, IdentityConstants.ExternalScheme);
var a = await h.AuthenticateAsync();

var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync();
_

GitHubを掘り下げて、実行中の内部コードをコピーしてコントローラーにコピーすると、クレームで_ClaimTypes.NameIdentifier_が見つからないことがわかります。これは後で使用されるProviderKeyです。

うーん...

古い1.x AccountControllerコードと新しい2.x識別ビットを使用していたのではないかと心配していました。私が持っているものを続けます。

そこで、次に、追加のGoogleユーザーJSONペイロードアイテムをクレームにマッピングすることを調査します。私のGoogleアカウントID(数値、私が推測する)がマップされていれば、すべてが機能すると思います。

https://docs.Microsoft.com/en-us/aspnet/core/security/authentication/social/additional-claims?view=aspnetcore-2.2

最終修正

「クレームアクション」を追加して、Googleから返されるJSONからGoogle識別子を引き出すことで、問題を最終的に解決しました。

_serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme)
    .AddGoogle(googleOptions =>
    {
        Configuration.Bind("OAuth2:Providers:Google", googleOptions);

        googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
    })
    .AddExternalCookie();
_

subフィールドには、最終的にnameidentifierクレームで終わり、ProviderKeyが必要とするAccountControllerに至るものが含まれます。

0
Luke Puplett

Google plus Enabledが必要になるのは事実です。私にとって大きなことは、プロジェクトのURLでした。 VSでプロパティウィンドウ([表示]-> [プロパティウィンドウ])を開き、プロジェクトを右クリックしてプロパティを選択します。小さなプロパティウィンドウでSSL URLをコピーし、大きなプロパティウィンドウで[Web]タブを選択して、そのURLをプロジェクトURLに貼り付けます。

私の問題を修正しました。

詳細を参照してください: https://docs.Microsoft.com/en-us/aspnet/mvc/overview/security/create-an-aspnet-mvc-5-app-with-facebook-and-google -oauth2-and-openid-sign-on

0

上記の答えはすべて良いですが、私の場合、これらはどれも機能しませんでした-Googleの設定を確認して再確認し、Chris Moschiniに多くの誤解を招く情報があることに同意しました。

私にとっては、アウトオブプロセス状態サービスが開始されなかったGetExternalLoginInfoAsyncからのNullだけで、エラーは発生しません(ログインは、ステートサービスがマシンで手動起動に設定されているリブート後に最初に試行したものでした)

これが誰かの助けになることを願っています。

0
JJones

私もこれに貢献したかった。私は最近これを機能させました。 GetExternalLoginInfoAsyncがnullを返す問題がありましたが、本番環境でのみ問題がありました。

多くの検索の後、私は最終的に私のデータベースの問題であるという答えを見つけました。本番環境では、正しく接続されないように間違った接続文字列を設定していましたが、基本的には無音でした。発生した唯一のことは、GetExternallLoginInfoAsyncがnullを返したことです。そのため、データベース接続文字列を確認してください。

また、補足として、これを機能させるために必要なことは次のとおりです。

  • Googleコンソールでプロジェクトをセットアップする
  • Google+ APIを有効にする
  • クライアントIDとクライアントシークレットをStartup.Auth.csファイルにコピーします。

HTTPSを有効にする必要はありません。カスタムルートを作成する必要もありません。ただし、データベースが正常に機能していることを確認してください!

0
Johan O

Stackoverflowで多くの検索と頭をひっくり返し、多数の赤いニシンの答えをたどった後、最終的にGoogle開発コンソールのすべてのオプションを確認し、Google + APIの概要ページに小さな青い[有効]ボタンを見つけました。私はこれをクリックして、それがうまくいったと言った。コールバックURLとルート設定について読んだすべてのバロニーを忘れて、OWINはいずれの場合もgoogleデフォルト/ signin-googleリダイレクトuriをオーバーライドし、ExternalLoginCallbackに送り返します。デフォルトの実装に固執するだけで、Google + APIを有効にすればすべて問題ありません。

0
Graham Walker