![](/img/trans.png)
[英]Instagram OAuth GetExternalLoginInfoAsync always returns null in .NET Core 2.0
[英]OWIN's GetExternalLoginInfoAsync Always Returns null
我創建了一個新的 MVC5 Web 應用程序,當我嘗試使用 Google 或 Facebook 登錄時,會調用AccountController
的ExternalLoginCallback
Action,但GetExternalLoginInfoAsync()
始終返回 null:
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
return RedirectToAction("Login");
}
因為它始終為空,所以它只是重定向回登錄頁面並重新開始該過程。 我怎樣才能解決這個問題?
為了讓 OWIN Google 登錄在標准的 Visual Studio 2013、ASP.Net MVC5 站點上正常工作,我必須:
在https://console.developers.google.com/project設置 Google OpenId 帳戶
將那里的回調 URL 設置為blah/signin-google
。
關於您不需要做的事情的重要說明:
您不需要使用 HTTPS 來讓 Google 重定向回來; 你甚至可以重定向回普通的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 為您的項目提供的任何端口號。
/account/ExternalLoginCallback
的請求包含&error=access_denied
,這是因為 Google 拒絕了 OWIN 為用戶的 Google+ 基本個人資料提出的權限請求。 我不知道這是誰的錯,谷歌的還是微軟的。要在開發人員控制台中啟用 Google+ API,請單擊左側的 API,搜索 Google+,單擊它並點擊啟用。 是的,您確實需要這樣做。 如果你不這樣做,你就會被灌輸。
將開發者控制台中谷歌給你的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
分開/signin-google
和 OWIN/Google 流程中的必要步驟。
好的,我找到了為什么它為空。 您必須在 Google 控制台中啟用 Google + API。 還要確保在將密鑰粘貼到代碼后,密鑰沒有在末尾連接一個空格。 為什么他們不能返回一個正常的錯誤? 我不知道。
似乎 Nuget 包 Microsoft.Owin.Security.Facebook 版本 3.0.1 不再適用於 Facebook 登錄。
將此包更新到預發布 3.1.0 版本,您可以使用以下內容:
安裝包 Microsoft.Owin.Security.Facebook -Pre
我通過簡單地更新應用程序中的所有 nugget 包來讓它工作,並且它工作正常。
我知道這很愚蠢,但經過長時間的斗爭,重新啟動 IIS 為我解決了這個問題。
這解決了我的問題:
啟用 Google+ API。 這是一個陷阱,是這里問題中問題的根本原因 - 如果你不這樣做,很容易錯過 Request to /account/ExternalLoginCallback
包含&error=access_denied
,這是因為谷歌對 a 說不OWIN 為用戶的 Google+ 基本個人資料提出的權限請求。 我不知道這是誰的錯,谷歌的還是微軟的。
要在開發人員控制台中啟用 Google+ API,請單擊左側的 API,搜索 Google+,單擊它並點擊啟用。
我做了以下工作來讓它工作。
登錄開發人員門戶,找到您的應用程序並執行以下操作。
我今天遇到了這個問題,結果是我在分配提供程序后定義了遠程 cookie。
確保你放置...
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
前...
app.UseFacebookAuthentication(
appId: "",
appSecret: "");
對於那些在 Web Api 上遇到此問題的人。 其他解決方案沒有幫助AuthenticationManager.GetExternalLoginInfoAsync();
即使啟用了 google plus api,也始終返回 null。
使用此自定義函數獲取登錄信息。 顯然,當通過 Web api 請求時,Microsoft 有一個 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;
}
盡管上面的答案都很好,但在我的例子中,這些都沒有奏效 - 我檢查並仔細檢查了 Google 設置,並同意 Chris Moschini 的觀點,即存在很多誤導性信息。
對我來說,當我意識到我的進程外狀態服務沒有啟動時,真是太棒了! 沒有錯誤(因為登錄是我在重新啟動后嘗試的第一件事,其中狀態服務設置為在機器上手動啟動)只是來自GetExternalLoginInfoAsync
的 Null
希望這可以幫助其他人。
經過大量搜索和摸索,並在 Stackoverflow 上遵循了無數的紅鯡魚答案后,我最終在我的 Google 開發控制台上瀏覽了所有選項,並在 Google+API 概述頁面上發現了一個藍色的 [啟用] 按鈕。 我點擊了這個,嘿,它很快就起作用了。 忘記您閱讀的有關回調 url 和路由配置的所有廢話,OWIN 在任何情況下都會覆蓋谷歌默認的 /signin-google 重定向 uri,並將您發送回 ExternalLoginCallback。 只要堅持使用默認實現,只要您啟用 Google+API,一切都會好起來的。
我也想為此做出貢獻。 我最近才開始工作。 我遇到了 GetExternalLoginInfoAsync 返回 null 但僅在生產中存在的問題。
經過大量搜索,我終於找到了答案,這只是我的數據庫有問題。 在生產中,我設置了錯誤的連接字符串,因此無法正確連接,但它基本上對此保持沉默。 唯一發生的事情是 GetExternallLoginInfoAsync 返回 null。 因此,如果發生這種情況,請檢查數據庫連接字符串!
同樣在旁注中,要使這項工作正常進行,唯一需要的是:
您不必啟用 HTTPS,也不必創建自定義路由。 但請確保您的數據庫工作正常!
確實,您將需要啟用 Google plus。 對我來說最重要的是項目 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 登錄
對我來說,我正在遷移和舊但工作 .NET 4.6.1 MVC 網站到核心 1.1。 工作在我開始工作之前就停止了,當我把它拿回來時,我正在遷移到 2.x。
我的問題是來自 Google 的回調遇到了來自我網站的404
。 我認為它應該命中AccountController.ExternalLoginCallback
所以我添加了一個[Route(...)]
到它,果然,谷歌的回調命中了這個動作。
這然后打null
該行返回(什么樣的瘋子回報的null
?)
var externalLoginInfo = await this.SignInManager.GetExternalLoginInfoAsync();
我對其進行了逆向工程,以發現它最終獲得了ExternalScheme
的處理程序,而我的則是 cookie 處理程序!
這一切似乎都錯了,我覺得中間件應該只是攔截回調 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 上的代碼)。 有趣的是, h
是CookieAuthenticationHandler
類型,而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 標識位,我確實找到了一些仍在使用這些東西的示例,以及一些使用 Razor Pages 的示例。 我會繼續我所擁有的。
所以我接下來要研究將額外的 Google 用戶 JSON 有效負載項目映射到聲明中。 我想如果我的 Google 帳戶 ID(我猜是數字)被映射,那么一切都會正常。
最終修復
我終於通過添加一個“聲明操作”來解決這個問題,將我的谷歌標識符從谷歌返回的 JSON 中提取出來!
serviceCollection.AddAuthentication(IdentityConstants.ExternalScheme)
.AddGoogle(googleOptions =>
{
Configuration.Bind("OAuth2:Providers:Google", googleOptions);
googleOptions.ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "sub", "string");
})
.AddExternalCookie();
sub
字段包含最終以nameidentifier
聲明結束的nameidentifier
,然后包含在AccountController
想要的ProviderKey
中。
在我的情況下,解決方案是更新 Nuget 包 Microsoft.Owin.Security 和 Microsoft.Owin.Security.Google
所有其他答案都沒有為我解決這個問題,因此如果您在同一條船上,請確保您的注冊控制器操作具有 RequireHttps 屬性:
// GET: /Account/LoginRegister
[AllowAnonymous]
[RequireHttps]
public ActionResult LoginRegister()
{
return View(new RegisterLoginViewModel());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.