Asp.net-Mvc

Google aspnet mvc5 上的 AuthenticationManager.GetExternalLoginInfoAsync() 返回 null

  • February 25, 2021

我使用預設的 Visual Studio 2015 模板和 Google 身份驗證開發了一個 ASPNET MVC 5 應用程序。在開發環境中一切正常,但在外部身份驗證後的實際呼叫AuthenticationManager.GetExternalLoginInfoAsync()有時會返回 null。

通常它在一天的中心時間(從 08:00 到 20:00)返回 null,但我沒有找到模式,因為有時在那個時候有效。我看過開發者控制台,但請求並不多(過去 12 小時內有 22 個),並且都成功了。

我嘗試了其他 StackOverflow 執行緒的一些解決方案,但沒有奏效。另外,我只能在晚上嘗試它們,因為這是一個個人項目,然後連接成功,我無法重現該問題。

程式碼是標準的:

  • 啟動時
public void ConfigureAuth(IAppBuilder app)
{
   // Configure the db context, user manager and signin manager to use a single instance per request
   app.CreatePerOwinContext(ApplicationDbContext.Create);
   app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
   app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

   // Enable the application to use a cookie to store information for the signed in user
   // and to use a cookie to temporarily store information about a user logging in with a third party login provider
   // Configure the sign in cookie
   app.UseCookieAuthentication(new CookieAuthenticationOptions
   {
       AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
       LoginPath = new PathString("/Account/Login"),
       Provider = new CookieAuthenticationProvider
       {
           // Enables the application to validate the security stamp when the user logs in.
           // This is a security feature which is used when you change a password or add an external login to your account.  
           OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
               validateInterval: TimeSpan.FromMinutes(30),
               regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
       }
   });            
   app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

   // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
   app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5));

   // Enables the application to remember the second login verification factor such as phone or email.
   // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from.
   // This is similar to the RememberMe option when you log in.
   app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie);

   var google = new GoogleOAuth2AuthenticationOptions()
   {
       ClientId = "xxxx",
       ClientSecret = "xxxx",
       Provider = new GoogleOAuth2AuthenticationProvider()
   };
   google.Scope.Add("email");
   app.UseGoogleAuthentication(google);
}
  • 在 ExternalLoginCallback 上
//
// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
   Log.Debug("AuthenticationManager.GetExternalLoginInfoAsync()");
   var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
   if (loginInfo == null)
   {
       Log.Error("AuthenticationManager.GetExternalLoginInfoAsync(): null");
       return RedirectToAction("Login");
   }
...

更多資訊

我已經與另一個使用者創建了新的 Google 憑據,當我更改 clientId 和 clientSecret 時,它又可以工作了……我什至不知道什麼時候……

還有更多資訊

問題不在於憑據,我“只”需要重新啟動 ASP.NET 應用程序來解決問題,也許這個新線索可以幫助某人幫助我。

沒有複製

我已經發布了答案,它不在OWIN 的 GetExternalLoginInfoAsync Always Returns null文章中,我已經提到了我找到解決方案的執行緒:ASP.NET_SessionId + OWIN Cookies do not send to browser

最後(我認為)一周後我找到了解決方案,沒有失敗的登錄。多虧了這個 StackOverflow 執行緒。我的解決方案是在操作中插入以下行AccountController.ExternalLogin

Session["Workaround"] = 0;

在上面的執行緒(以及那裡提供的連結)中,找到了對混合 ASPNET MVC 和 OWIN 組件的會話和 cookie 時的錯誤的更好解釋。

完整的控制器服務程式碼:

   //
   // POST: /Account/ExternalLogin
   [HttpPost]
   [AllowAnonymous]
   [ValidateAntiForgeryToken]
   public ActionResult ExternalLogin(string provider, string returnUrl)
   {
       // https://stackoverflow.com/questions/20737578/asp-net-sessionid-owin-cookies-do-not-send-to-browser
       Session["Workaround"] = 0;
       // Request a redirect to the external login provider
       return new ChallengeResult(provider, Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl }));
   }

引用自:https://stackoverflow.com/questions/40269783