Периодическая проблема oAuth в ASP.NET с Google, AuthenticationManager.GetExternalIdentityAsync возвращает значение NULL
Я пытаюсь исправить периодически возникающую проблему при использовании Google в качестве внешнего поставщика входа в систему.
При попытке входа в систему пользователь перенаправляется обратно на страницу входа в систему, а не проходит проверку подлинности.
Проблема возникает в этой строке (строка 55 ссылки ниже), GetExternalIdentityAsync возвращает значение NULL.
var externalIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
Полный код:
[Authorize]
public abstract class GoogleAccountController<TUser> : Controller where TUser : Microsoft.AspNet.Identity.IUser
{
public IAuthenticationManager AuthenticationManager
{
get
{
return HttpContext.GetOwinContext().Authentication;
}
}
public abstract UserManager<TUser> UserManager { get; set; }
[AllowAnonymous]
[HttpGet]
[Route("login")]
public ActionResult Login(string returnUrl)
{
ViewData.Model = new LoginModel()
{
Message = TempData["message"] as string,
Providers = HttpContext.GetOwinContext().Authentication.GetExternalAuthenticationTypes(),
ReturnUrl = returnUrl
};
return View();
}
[AllowAnonymous]
[HttpPost]
[ValidateAntiForgeryToken]
[Route("login")]
public ActionResult Login(string provider, string returnUrl)
{
return new ChallengeResult(provider, Url.Action("Callback", "Account", new { ReturnUrl = returnUrl }));
}
[AllowAnonymous]
[Route("authenticate")]
public async Task<ActionResult> Callback(string returnUrl)
{
var externalIdentity = await AuthenticationManager.GetExternalIdentityAsync(DefaultAuthenticationTypes.ExternalCookie);
if (externalIdentity == null)
{
return RedirectToAction("Login", new { ReturnUrl = returnUrl });
}
var emailAddress = externalIdentity.FindFirstValue(ClaimTypes.Email);
var user = await UserManager.FindByNameAsync(emailAddress);
if (user != null)
{
await SignInAsync(user, false);
return RedirectToLocal(returnUrl);
}
else
{
TempData.Add("message", string.Format("The account {0} is not approved.", emailAddress));
return RedirectToAction("Login", new { ReturnUrl = returnUrl });
}
}
[HttpPost]
[ValidateAntiForgeryToken]
[Route("logout")]
public ActionResult Logout(string returnUrl)
{
AuthenticationManager.SignOut();
return RedirectToLocal(returnUrl);
}
private async Task SignInAsync(TUser user, bool isPersistent)
{
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
var authenticationProperties = new AuthenticationProperties()
{
IsPersistent = isPersistent
};
AuthenticationManager.SignIn(authenticationProperties, identity);
}
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
protected override void Dispose(bool disposing)
{
if (disposing && UserManager != null)
{
UserManager.Dispose();
UserManager = null;
}
base.Dispose(disposing);
}
}
Что такжеВот.
Это очень частая проблема, и повторное развертывание приложения часто заставит его работать временно.
Посмотрев в Fiddler, я вижу, что сделан вызов для входа в Google прямо перед методом аутентификации, в котором он не может найти cookie.
Приложение использует следующий код для инициализации входа в Google
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
LoginPath = new PathString("/login")
});
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseGoogleAuthentication();
Я установил режим аутентификации non в файле web.config и удалил модуль аутентификации форм.
<system.web>
<authentication mode="None" />
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false" />
<modules runAllManagedModulesForAllRequests="true">
<remove name="FormsAuthenticationModule" />
</modules>
</system.webServer>
Сайты размещены в Azure, некоторые из них работают на 1 экземпляре, некоторые на 2. Они имеют собственные домены, хотя по-прежнему отказывают как в настраиваемом домене, так и в домене azurewebsites, а также в http / https.
Может кто-нибудь помочь с тем, почему это может происходить?
Обновить
Версия 3.0 Microsoft.Owin.Security.Google была выпущена вчера вечером. Собираюсь переключиться и посмотреть, решит ли это проблему.
https://www.nuget.org/packages/Microsoft.Owin.Security.Google