GoogleOauth2 问题获取内部服务器 500 错误

Posted

技术标签:

【中文标题】GoogleOauth2 问题获取内部服务器 500 错误【英文标题】:GoogleOauth2 Issue Getting Internal Server 500 error 【发布时间】:2014-02-23 04:14:15 【问题描述】:

我决定试一试新的 Google Oauth2 中间件,它几乎破坏了一切。这是我来自 startup.auth.cs 的提供程序配置。打开后,包括 google 提供程序在内的所有提供程序都会在 Challenge 上获得 500 个内部服务器。但是,内部服务器错误的详细信息不可用,我无法弄清楚如何为 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);

动作方法代码:

 [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();
    

【问题讨论】:

我不确定具体问题是什么 - 您可以尝试为 Google 软件包设置符号,看看哪里出了问题。以下是为武士刀设置符号的一些说明 - katanaproject.codeplex.com/… 这似乎是 CallBackPath 的问题。是否有可能在为此提供者设置回调路径时为所有提供者全局设置该道具。 src还没挖,只是一个想法…… 当你说所有提供者的全局属性 => 你想为所有提供者设置相同的值吗?无法为所有提供者自动设置相同的值,但您可以根据需要手动设置它们。您应该确保在相应门户的相应应用程序设置中注册了此重定向 uri。如果您没有明确提供,则这些中间件中的每一个都有一个默认的 CallBackPath。例如,这个 google 中间件的默认值为 /signin-google。 我认为您没有理解我的问题。我确实看到了每个提供者的财产。我想知道是否以某种方式为一个提供者设置属性会应用于所有其他 Oauth2 提供者。 我不这么认为。我无法重现此问题。您介意上传一个在某处重现此问题的独立项目吗? 【参考方案1】:

我花了几个小时才弄清楚,但问题是@CrazyCoder 提到的CallbackPath。我意识到public void ConfigureAuth(IAppBuilder app) 中的CallbackPath 必须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);
    

callbacks/google 似乎由 OWIN 处理 回调/googlereturn 似乎由 MVC 处理

现在一切正常,虽然很想知道“引擎盖下”到底发生了什么

除非您有其他要求,否则我的建议是让 OWIN 使用默认重定向路径,并确保您自己不要使用它们。

【讨论】:

对不起,我很久以前忘记回答了。 澄清是什么为我解决了这个问题:1)account.live.com 应用程序区域(API 设置)中的重定向 URL 设置设置为“http:///Account/MicrosoftLoginCallback” 2) 回调路径设置为 "PathString("/Account/MicrosoftLoginCallback");"对于 IAppBuilder:app.UseMicrosoftAccountAuthentication(new MicrosoftAccountAuthenticationOptions CallbackPath = msCallbackPath, ClientId =, ClientSecret = 3) 用于质询的 RedirectUri 必须从“MicrosoftLoginCallback”更改为“MSLoginCallback”,仅在 AccountController 操作和 Authentication.Challenge( ) 调用。 简而言之,当上述所有三个项目的名称都匹配时,我得到了一个 500 错误,并且没有什么可继续的了。在 Fiddler 中,我认为微软实际上是在回调“Account/MicrosoftLoginCallback”(为 IAppBuilder 配置)。但是,infrastrucutre/provider 中的某些内容可能会将其映射到“Account/MSLoginCallback”(我为质询 AuthenticationProperties 对象提供的实际控制器操作方法。 已作为 UserVoice 错误发布,请 UPVOTE,aspnet.uservoice.com/forums/41199-general-asp-net/suggestions/…【参考方案2】:

UseGoogleAuthentication中不需要指定CallbackPath

CallbackPath = new PathString("/Account/ExternalLoginCallback")

只需将授权重定向 URIs 的 Google 设置保留为:

http(s)://yoururl:orPort/signin-google

Owin 在内部处理 signin-google 并重定向到您在 ChallengeResult 类的代码中提到的 redirectUri。哪个是 Account/ExternalLoginCallback。

【讨论】:

这应该被标记为解决方案。像魅力一样为我工作。 我还要注意,调用 /Account/ExternalLogin(即localhost:44300/Account/…)时,通过网络浏览器单击登录按钮时的提供程序参数应该是“Google” 当你说谷歌设置你指的是什么?对于没有任何经验的人来说,这个答案似乎不够清晰。你是在说 CallBackPath 吗? Google 设置是您在创建 oAuth 令牌时在 Google 开发控制台中提供的值,developers.google.com/identity/sign-in/web/devconsole-project 这是最好的答案。许多其他答案建议添加路由映射以将回调重定向到 MVC 中的正确方法,但这只会使服务器崩溃。【参考方案3】:

通过一个简单的更改从教程中得到它的工作香草 - 只需为任何使用这种方法的 nubes 发布此内容。我认为在这种情况下与 oauth2 相关的问题在很大程度上体现在最新的模板/api 中——我的意思是,如果你从头开始,你可能会很幸运——继续阅读:

我刚刚完成了这个教程 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+ api 之后。

(只需转到 google api lib manager,登录并在 apis 目录中搜索 google+ api)。 注意:对我来说,Google+ api 默认是禁用的。

我没有做任何其他独特的事情。

干杯

【讨论】:

【参考方案4】:

到目前为止给出的答案让我走上了一条我希望我没有走过的非常黑暗的道路......解决方案很简单,确保以下 3 件事匹配:

1) 在 Google OATH 凭证 (https://console.developers.google.com/) 中:

重定向 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 再次与其他 2 具有相同的 PathString

最后,如果您仍然没有收到它,请在您的应用中将您的身份验证模式设置为“无”Web.config

<authentication mode="None" />

获取有关该问题的更多详细信息。

【讨论】:

【参考方案5】:

为了简单起见,我使用带有身份验证的默认 ASP.NET MVC 5 模板,但希望可以针对不同的用例进行修改。

StartupAuth.cs

不要自定义重定向路径。无论如何,它都被 /signin-google 取代了,而我试图绕过这导致“静默”(不在调试器中)内部服务器 500 错误。

app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions()

    ClientId = "whatevs.apps.googleusercontent.com",
    ClientSecret = "whatevs_secrut",
    Provider = new GoogleOAuth2AuthenticationProvider()
);

确保在APIs &amp; auth > Credentials > Redirect URIs 部分中将http://whatever.com/signin-google 添加到https://console.developers.google.com/。

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

【讨论】:

这个答案不正确。 /signin-google 由 OWIN 处理,无论你添加与否,它都被忽略; OWIN 在 MVC 路由首先接触它之前处理请求。 OWIN 不需要任何帮助来处理 /signin-google URL - 这不是问题。 @ChrisMoschini 请不要说有什么不正确,除非您实际尝试过。我有,而且它有效,这就是为什么我不仅发布了对这个问题的回复,而且将解决方案上传到了 GitHub。关键是在 ASP.NET MVC 中,您仍然需要一个控制器操作来处理身份验证响应,并且在 Microsoft 提供的示例中,为 OWIN 提供程序提供自定义重定向路径不起作用。我不是在“帮助”OWIN 找到 /signin-google。我正在帮助 HTTP 管道正确地将自身重定向到 Account/ExternalLoginCallbackRedirect。 @ChrisMoschini 澄清一下,您可以为 Home/signin-google 实现控制器操作。此答案解决的问题是重定向到其他一些控制器操作,这无法通过向 OWIN 提供程序提供重定向 URI 来完成。无论您为提供者提供什么 URI,它都会被框架自动覆盖为 /signin-google。我希望澄清这个答案的目的,我将真诚地假设混淆已找到。 我今天尝试了这个方法来解决一个问题,但它似乎没有用。起作用的是将 machineKey 添加到 web.config 中。添加 machineKey 后一切正常。

以上是关于GoogleOauth2 问题获取内部服务器 500 错误的主要内容,如果未能解决你的问题,请参考以下文章

Google OAuth2 不适用于移动设备

在 Graphql 突变上获取内部服务器错误 500

google oauth2:为 Web 服务器应用程序上的授权用户重新获取 refresh_token

具有公共访问权限的 Web 应用程序的 Google OAuth 2.0 刷新令牌

无法在 POSTMan 上获取 Google oAuth 2 令牌

Google OAuth2 登录 - 获取 YouTube 昵称和真实电子邮件地址