GoogleOAuth2 始终 return 拒绝访问回调 url

GoogleOAuth2 always return access denied to callback url

我正在尝试使用来自 Microsoft.Owin.Security.Google

GoogleAuthenticationExtensions

MVC5 程序中的包。这是我的 StartUp.cs :

   var googlePlusOptions = new GoogleOAuth2AuthenticationOptions {};
    googlePlusOptions.ClientId = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX.apps.googleusercontent.com";
    googlePlusOptions.AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/auth";
    googlePlusOptions.TokenEndpoint = "https://oauth2.googleapis.com/token";
    googlePlusOptions.ClientSecret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
    googlePlusOptions.CallbackPath = new PathString("/GoogleLoginCallback");
    app.UseGoogleAuthentication(googlePlusOptions);

以及 LoginController 中的 SignInMethod 方法:

[HttpGet]
[AllowAnonymous]
public void SignInGoogle(string ReturnUrl = "/", string type = "")
{
    if (!Request.IsAuthenticated)
    {
        if (type == "Google")
        {
            var owinContext = HttpContext.GetOwinContext();
            owinContext.Authentication.Challenge(new AuthenticationProperties { RedirectUri = "Login/GoogleLoginCallback" }, "Google");
            Response.StatusCode = 401;
            Response.End();
        }
    } 
}

和 CallBack Url 在同一控制器中:

[AllowAnonymous]
    public ActionResult GoogleLoginCallback()
    {
        var claimsPrincipal = HttpContext.User.Identity as ClaimsIdentity;

        var loginInfo = GoogleLoginViewModel.GetLoginInfo(claimsPrincipal);
        if (loginInfo == null)
        {
            return RedirectToAction("Index");
        }



        var user = db.UserAccounts.FirstOrDefault(x => x.Email == loginInfo.emailaddress);

        if (user == null)
        {
            user = new UserAccount
            {
                Email = loginInfo.emailaddress,
                GivenName = loginInfo.givenname,
                Identifier = loginInfo.nameidentifier,
                Name = loginInfo.name,
                SurName = loginInfo.surname,
                IsActive = true
            };
            db.UserAccounts.Add(user);
            db.SaveChanges();
        }

        var ident = new ClaimsIdentity(
                new[] { 
                            // adding following 2 claim just for supporting default antiforgery provider
                            new Claim(ClaimTypes.NameIdentifier, user.Email),
                            new Claim("http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider", "ASP.NET Identity", "http://www.w3.org/2001/XMLSchema#string"),

                            new Claim(ClaimTypes.Name, user.Name),
                            new Claim(ClaimTypes.Email, user.Email),
                            // optionally you could add roles if any
                            new Claim(ClaimTypes.Role, "User")
                },
                CookieAuthenticationDefaults.AuthenticationType);


        HttpContext.GetOwinContext().Authentication.SignIn(
                    new AuthenticationProperties { IsPersistent = false }, ident);
        return Redirect("~/");

    }

现在程序进入 Google 的登录屏幕,但是当它返回到回调 Url 时

loginInfo 为空。这是回调 Url 的响应:

到目前为止我所做的事情没有任何结果: 1-激活 Google+ APi 2-将 nuget 更新到最新版本 (4.2 atm) 3-将电子邮件添加到 TestUser 或将 google 控制台中的项目更改为生产 4-在 google 控制台中添加并填写同意部分 5-将 js 回调设置为空白

有点奇怪的是,如果我修改 ClientId,google 的登录屏幕将阻止我,但如果我更改 secretId,则什么也不会发生,但我仍然看到上面的错误。 我今天从 OAuth 控制台面板得到了他们两个 (ClientId,SecretId)。

对于这类问题,如果不重新创建完整的环境设置,就很难准确指出问题出在哪里。所以我只能尝试解释发生了什么,但要获得更精确的解决方案,您将不得不深入研究它。

基本上我不确定您对 OpenIDConnect 和 OAuth2.0 流程了解多少,但我可以描述您的场景中发生的情况。

  1. 您的应用程序正在将用户重定向到 google 登录页面
  2. 用户正在登录
  3. 成功登录后 google 使用这些查询参数将用户浏览器重定向回您的应用程序(屏幕截图的第三行)
  4. 现在您的应用程序应采用这些参数并将其发送到反向通道(服务器到服务器请求)中的 google,以将其从 google 交换为 access_token。这是一个棘手的部分 - 可能你认为你正在立即执行 GoogleLoginCallback 方法 - 但你没有。真正发生的是 GoogleAuthentication Middleware 承担了这个责任。它确定该请求是 OpenIDConnect 流程的一部分,并将尝试为您获取令牌并在您的上下文中设置身份。
  5. 不幸的是出了点问题,因为您使用 ?error=access_denied 参数进行了另一个重定向。这完全由 Katana 项目的 GoogleOAuth2AuthenticationHandler 实现完成:https://github.com/aspnet/AspNetKatana/blob/beb224c88712b08ce45f1d14bb8cf0cd9d4a8503/src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs#L259 这是执行此操作的代码。我认为您应该使用此存储库来识别流程以及可能出现的问题(出于某种原因,您的 context.Identity 似乎是 null)。
  6. 现在在那个重定向上你终于执行了你的控制器方法GoogleLoginCallback但我猜是因为上一步失败了 - 我们在那个请求中没有正确的身份状态。

您没有分享更多 Startup.cs 但您应该使用 .UseCookieAuthentication(),如 Katana 示例 https://github.com/aspnet/AspNetKatana/blob/beb224c88712b08ce45f1d14bb8cf0cd9d4a8503/samples/Katana.Sandbox.WebServer/Startup.cs#L83

我认为您需要更改的绝对是您需要更改或删除设置 CallbackPath 属性 用于识别 OpenID 流程步骤 https://github.com/aspnet/AspNetKatana/blob/beb224c88712b08ce45f1d14bb8cf0cd9d4a8503/src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationHandler.cs#L224. This callback is only for the purpose of exchanging for the access token and default value is /signin-google https://github.com/aspnet/AspNetKatana/blob/dbe159e43e2eee44f315f26268943e8ab5a4f60d/src/Microsoft.Owin.Security.Google/GoogleOAuth2AuthenticationOptions.cs#L28 因此 GoogleAuthenticationHandler 每次都会启动您将尝试访问您的控制器方法。

抱歉,如果这仍然没有帮助。但我认为你应该有足够的资源来慢慢找到你的解决方案。如果您仍然无法确定问题,我的建议是将 类 从 Katana github 复制到您的项目中,重命名,然后整个流程应该是 'debbugable'.

然后回答你的最后一个问题: