Ошибка GoogleOauth2: получение внутренней ошибки сервера 500
Я решил попробовать новое промежуточное программное обеспечение Google Oauth2, и оно почти все сломало. Вот моя конфигурация провайдера от startup.auth.cs. Когда она включена, все провайдеры, включая провайдера Google, получают 500 внутренних серверов на Challenge. Однако детали внутренней ошибки сервера недоступны, и я не могу понять, как включить любую отладку или трассировку для промежуточного программного обеспечения Katana. Мне кажется, что они спешат вытащить связующее ПО Google Oauth за дверь.
//// GOOGLE
var googleOptions = new GoogleOAuth2AuthenticationOptions
{
ClientId = "228",
ClientSecret = "k",
CallbackPath = new PathString("/users/epsignin")
SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie,
Provider = new GoogleOAuth2AuthenticationProvider
{
OnAuthenticated = context =>
{
foreach (var x in context.User)
{
string claimType = string.Format("urn:google:{0}", x.Key);
string claimValue = x.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new Claim(claimType, claimValue, XmlSchemaString, "Google"));
}
return Task.FromResult(0);
}
}
};
app.UseGoogleAuthentication(googleOptions);
Код ActionMethod:
[AllowAnonymous]
public ActionResult ExternalProviderSignIn(string provider, string returnUrl)
{
var ctx = Request.GetOwinContext();
ctx.Authentication.Challenge(
new AuthenticationProperties
{
RedirectUri = Url.Action("EPSignIn", new { provider })
},
provider);
return new HttpUnauthorizedResult();
}
5 ответов
Мне понадобилось несколько часов, чтобы понять, но проблема в том, CallbackPath
как упомянуто @CrazyCoder. Я понял, что CallbackPath
в public void ConfigureAuth(IAppBuilder app)
ДОЛЖЕН отличаться от того, когда он установлен в ChallengeResult
, Если они одинаковые, в OWIN выдается ошибка 500.
Мой код для ConfigureAuth(IAppBuilder app)
является
var googleOptions = new Microsoft.Owin.Security.Google.GoogleOAuth2AuthenticationOptions
{
ClientId = "xxx",
ClientSecret = "yyy",
CallbackPath = new PathString("/callbacks/google"), //this is never called by MVC, but needs to be registered at your oAuth provider
Provider = new GoogleOAuth2AuthenticationProvider
{
OnAuthenticated = (context) =>
{
context.Identity.AddClaim(new Claim("picture", context.User.GetValue("picture").ToString()));
context.Identity.AddClaim(new Claim("profile", context.User.GetValue("profile").ToString()));
return Task.FromResult(0);
}
}
};
googleOptions.Scope.Add("email");
app.UseGoogleAuthentication(googleOptions);
Мой код контроллера обратных вызовов:
// GET: /callbacks/googlereturn - callback Action
[AllowAnonymous]
public async Task<ActionResult> googlereturn()
{
return View();
}
//POST: /Account/GooglePlus
public ActionResult GooglePlus()
{
return new ChallengeResult("Google", Request.Url.GetLeftPart(UriPartial.Authority) + "/callbacks/googlereturn", null);
//Needs to be a path to an Action that will handle the oAuth Provider callback
}
private class ChallengeResult : HttpUnauthorizedResult
{
public ChallengeResult(string provider, string redirectUri)
: this(provider, redirectUri, null)
{
}
public ChallengeResult(string provider, string redirectUri, string userId)
{
LoginProvider = provider;
RedirectUri = redirectUri;
UserId = userId;
}
public string LoginProvider { get; set; }
public string RedirectUri { get; set; }
public string UserId { get; set; }
public override void ExecuteResult(ControllerContext context)
{
var properties = new AuthenticationProperties() { RedirectUri = RedirectUri };
if (UserId != null)
{
properties.Dictionary[XsrfKey] = UserId;
}
context.HttpContext.GetOwinContext().Authentication.Challenge(properties, LoginProvider);
}
}
- обратные вызовы / Google, кажется, обрабатываются OWIN
- обратные вызовы /googlereturn, похоже, обрабатываются MVC
Сейчас все работает, хотя хотелось бы точно знать, что происходит "под капотом"
Мой совет, если у вас нет другого требования, разрешить OWIN использовать пути перенаправления по умолчанию и убедиться, что вы не используете их самостоятельно.
Нет необходимости указывать CallbackPath
в UseGoogleAuthentication
:
CallbackPath = new PathString("/Account/ExternalLoginCallback")
Просто сохраните настройки Google для авторизованного перенаправления URIs
как:
http (s): // yoururl: orPort /signin-google
Овин обрабатывает signin-google изнутри и перенаправляет на redirectUri, как указано в вашем коде для класса ChallengeResult. Который является Account/ExternalLoginCallback.
Понял, что в учебнике все в порядке с ОДНИМ простым изменением - просто опубликовать это для любых сфер этого подхода. Я думаю, что проблемы, связанные с oauth2 в этом случае, в основном освещены в последних шаблонах / apis - я имею в виду, что если вы начинаете с нуля, вам может повезти - читайте дальше:
Я ПРОСТО сделал это руководство https://azure.microsoft.com/en-us/documentation/articles/web-sites-dotnet-deploy-aspnet-mvc-app-membership-oauth-sql-database/
и ссылался на это также http://blogs.msdn.com/b/webdev/archive/2014/07/02/changes-to-google-oauth-2-0-and-updates-in-google-middleware-for-3-0-0-rc-release.aspx
Единственное изменение: это сработало, но ТОЛЬКО после включения google+ apis в последней версии сайта разработчиков Google.
(Просто зайдите в google api lib manager, войдите в систему и найдите в каталоге apis google+ api).
Примечание: для меня API Google+ был отключен по умолчанию.
Я не сделал ничего другого уникального.
ура
Ответы, данные до сих пор, привели меня по очень темному пути, который я хотел бы не пройти... решение простое, убедитесь, что следующие 3 вещи совпадают:
1) В учетных данных Google OATH ( https://console.developers.google.com/):
- У REDIRECT URIS есть https://localhost:44300/Account/ExternalLoginCallback (Зафиксируйте свой порт на том, что вы используете)
2) В вашем AccountController
:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ExternalLogin(string provider, string returnUrl)
{
return new ChallengeResult(provider,
Url.Action("ExternalLoginCallback", "Account",
new { ReturnUrl = returnUrl }));
}
Обратите внимание, что действие "ExternalLoginCallback"
3) В вашем App_Start\Startup.Auth.cs
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = "yourclientid.apps.googleusercontent.com",
ClientSecret = "yoursecret",
Provider = new GoogleOAuth2AuthenticationProvider(),
CallbackPath = new PathString("/Account/ExternalLoginCallback")
});
Обратите внимание на CallbackPath
снова имеет то же самое PathString
как и другие 2
Наконец, если вы все еще не получаете его, установите для вашего режима аутентификации значение Нет в вашем приложении. Web.config
<authentication mode="None" />
чтобы получить более подробную информацию о проблеме.
Я использую шаблон ASP.NET MVC 5 по умолчанию с Identity Authentication для простоты, но, надеюсь, это можно изменить для разных случаев использования.
StartupAuth.cs
Не настраивайте путь перенаправления. В любом случае он заменяется на /signin-google, и мои попытки обойти это вызвали "тихий" (не в отладчике) внутренний сервер 500 ошибок.
app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()
{
ClientId = "whatevs.apps.googleusercontent.com",
ClientSecret = "whatevs_secrut",
Provider = new GoogleOAuth2AuthenticationProvider()
});
Обязательно добавьте http://whatever.com/signin-google в https://console.developers.google.com/ в своем APIs & auth
> Credentials
> Redirect URIs
раздел.
RouteConfig.cs
Добавьте маршрут к действию контроллера постоянного перенаправления в ваши маршруты. Постоянные перенаправления - единственное, что здесь будет достаточно. Недостаточно просто напрямую перейти к URL обратного вызова.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Google API Sign-in",
url: "signin-google",
defaults: new { controller = "Account", action = "ExternalLoginCallbackRedirect" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
AccountController.cs
Постоянное перенаправление на встроенный метод обратного вызова, и у вас все должно быть в порядке.
[AllowAnonymous]
public ActionResult ExternalLoginCallbackRedirect(string returnUrl)
{
return RedirectPermanent("/Account/ExternalLoginCallback");
}
Шаблон проекта был размещен на GitHub для справки: https://github.com/Pritchard/Test-AspNetGoogleOAuth2Authentication