OWIN的GetExternalLoginInfoAsync始终返回null

69

我创建了一个新的MVC5 Web应用程序,当我尝试使用Google或Facebook登录时,AccountController中的ExternalLoginCallback操作被调用,但是GetExternalLoginInfoAsync()始终返回null:

var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
if (loginInfo == null)
{
    return RedirectToAction("Login");
}
因为它始终为空,所以它只会重定向回登录页面,并且流程重新开始。我该如何解决这个问题?

请看一下:http://www.asp.net/mvc/tutorials/mvc-5/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on。我昨天按照这个教程进行操作,没有遇到任何问题。 - Felipe Miosso
你是否检查了在ExternalLogin ActionResult的ChallengeResult中传递的正确提供程序? - Santosh
2
遇到了相同的问题。是的,提供者是正确的。我点击登录,被重定向到Facebook,我登录,然后被重定向到了方法...但是 loginInfo 为 null。 - nVentimiglia
1
遇到了同样的问题。重启IIS后,问题得到了解决。这个问题有没有更好的解决方案? - Lee
7
我有同样的问题,我忘记打开Google+ API。 - sabotero
显示剩余2条评论
17个回答

106

为了让OWIN Google登录在标准的Visual Studio 2013,ASP.Net MVC5网站上正常工作,我需要执行以下操作:

  1. https://console.developers.google.com/project上设置Google OpenId帐户

  2. 将回调URL设置为blah/signin-google
    关于一些你不需要做的事情的重要说明:

    • 你不需要使用HTTPS来让Google重定向回来;甚至可以重定向回到普通的http://localhost,没问题。

    • 你不需要为重定向URL设置任何东西-不需要路由、控制器行为或者在Web.Config中设置特殊权限。重定向URL始终是/signin-google,OWIN会在幕后为您处理这个问题。

举例来说,如果你的网站是me.com,你可能会在Google Developer Console中有这3个回调URL:

http://localhost:53859/signin-google
http://test.me.com/signin-google
https://me.com/signin-google

第一个端口号包括VS为您的项目分配的任何端口号。

  1. 启用Google+ API。这是一个隐藏的困扰,也是这个问题的根本原因 - 如果您没有这样做,很容易忽略到请求中包含&error=access_denied,这是因为Google拒绝了OWIN对用户的Google+基本档案的权限请求。我无法确定这是谁的错,是谷歌还是微软。

要在开发人员控制台中启用Google+ API,请单击左侧的API,搜索Google+,然后单击启用。是的,您确实需要这样做。如果您不这样做,您将无法使用。

  1. 向Startup.Auth添加Google在开发人员控制台中提供的ClientId和ClientSecret,并在此过程中改进代码以明确使用OAuth2,并显式请求用户的电子邮件地址:

    var google = new GoogleOAuth2AuthenticationOptions()
    {
        ClientId = "123abc.apps.googleusercontent.com",
        ClientSecret = "456xyz",
        Provider = new GoogleOAuth2AuthenticationProvider()
    };
    google.Scope.Add("email");
    app.UseGoogleAuthentication(google);
    

就是这样。最终终于搞定了。

再强调一遍,有很多关于OWIN/Google无法使用的问题的答案,几乎所有这些答案都对于当前的VS2013/MVC5/OWIN模板来说已经过时。
您根本不需要修改Web.Config。
您不需要创建任何特殊的路由。
您不应该尝试将/signin-google指向其他位置,或者使用不同的回调URL,您绝不能直接将其与/account/externallogincallbackexternalloginconfirmation相关联,因为它们都是OWIN / Google过程中必要的步骤,与/signin-google是分开的。


12
第三个解决方案对我有用。可悲的是,我过去知道这就是问题所在,但已经忘记了... 是的,完全赞同这很麻烦。非常感谢提供列表。 - roboto1986
4
谢谢,谢谢,谢谢!生效了,是的,启用了Google+ API,即使没有“代码改进”也生效了。非常详细的答案! - Pawel Cioch
1
如果我能给你点赞1000次,我一定会的。谢谢! - Giovanni Galbo
4
对我来说不起作用。实际上,在未启用Google+ API的情况下创建appID和appSecret是不可能的。我已经启用了它并成功创建了密钥和ID,但我仍然被重定向回登录页面。 - tutiplain
2
我已经启用了它,但它仍然无法工作。考虑手动执行Oauth流程,因为这似乎是Owin或Visual Studio项目模板中的错误。 - tutiplain
显示剩余4条评论

46

好的,我找到了为什么它是null。您需要在Google控制台中启用Google + API。此外,请确保将秘密密钥粘贴到代码后,不要在末尾拼接空格。为什么他们不能返回正常错误?我不知道。


6
这立刻解决了问题。不错的发现,谢谢。 - James Mauldin
现在我仔细看,发现这一步骤在asp.net的说明中清晰地指出了。 - James Mauldin
是的,但我认为这不是必须的。无论如何,它与显示的错误之间的连接并不清楚。 - Ronen Festinger
是的,我看过各种疯狂的答案,但这个对我来说是正确的。 - Papa Burgundy
您,先生,真是太厉害了! - Kris

20

看起来 Nuget 包 Microsoft.Owin.Security.Facebook 版本 3.0.1 不再支持 Facebook 登录。

如果您想升级到预发布版本 3.1.0,可以使用以下命令:

Install-Package Microsoft.Owin.Security.Facebook -Pre


2
天啊,希望他们能尽快修复这个问题。我整晚都在重新配置URL,试图弄清楚自上次玩耍以来我无意中更改了什么。你的建议很有用。根据NuGet,仍然没有可安装的3.0.1之后的更新版本。 - Richard
^^ Richard 说的话 - raklos
1
在尝试了 Stack Overflow 上的几乎所有方法并浪费了约 3 小时后,这是我最终的解决方案。谢谢 :) - Dan Cook
它看起来不再是预发布版本,现在是真正的版本了。 - Luke
1
升级到3.1版本解决了我的问题。感谢您节省了我许多痛苦的调试时间! - johnnyRose
显示剩余2条评论

7
如其他人所说,大多数情况下,这是因为您没有访问Google+ API的权限,以下是如何在Google API管理器中为项目授权以使用Google+ API: 步骤1:从顶部下拉框中选��您的项目,进入“仪表板”>“启用API” enter image description here 步骤2:搜索“Google+”,并选择它 enter image description here 步骤3:启用它! enter image description here 如果您回到该项目的仪表板,您可以看到页面底部列出了该项目已启用的API列表。 enter image description here

4

我通过简单地更新应用程序中的所有NuGet包来使其正常工作。


这对我也起作用了,在尝试了这里提到的所有其他方法之后。我将OWIN包从v4.0.0更新到v4.0.1,然后它开始工作了。 - christiaantober

3
这解决了我的问题:
启用Google+ API。这是一个陷阱,也是此处问题的根本原因 - 如果您不这样做,很容易忽略请求 /account/ExternalLoginCallback 中包含的&error=access_denied,这是因为Google拒绝了OWIN对用户的Google+基本配置文件的权限请求。我无法确定这是谁的错,是Google还是Microsoft。 要在开发人员控制台中启用Google+ API,请单击左侧的API,搜索Google+,然后单击启用。

3

我知道这很傻,但经过长时间的挣扎后,重新启动IIS解决了我的问题。


同样的问题在这里也出现了,但是过了一段时间(几天)后又回来了。它运行得很好,然后突然就停止了,重新刷新应用程序池就可以再次解决。非常奇怪。 - Patrick
这对我解决了问题。希望现在它能一直工作。 - Patrick

1
今天我遇到了这个问题,结果发现我在分配提供者之后定义了远程cookie。
请确保您放置...
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);

之前...

app.UseFacebookAuthentication(
                   appId: "",
                   appSecret: "");

1
对于那些在Web Api中遇到此问题的人。其他解决方案无法帮助,即使启用了Google Plus API,AuthenticationManager.GetExternalLoginInfoAsync();始终返回null。使用此自定义函数获取logininfo。显然,当在Web Api上请求时,Microsoft存在一个GetExternalLoginInfoAsync的bug。
private async Task<ExternalLoginInfo> AuthenticationManager_GetExternalLoginInfoAsync_WithExternalBearer()
        {
            ExternalLoginInfo loginInfo = null;

            var result = await Authentication.AuthenticateAsync(DefaultAuthenticationTypes.ExternalBearer);

            if (result != null && result.Identity != null)
            {
                var idClaim = result.Identity.FindFirst(ClaimTypes.NameIdentifier);
                if (idClaim != null)
                {
                    loginInfo = new ExternalLoginInfo()
                    {
                        DefaultUserName = result.Identity.Name == null ? "" : result.Identity.Name.Replace(" ", ""),
                        Login = new UserLoginInfo(idClaim.Issuer, idClaim.Value)
                    };
                }
            }
            return loginInfo;
        }

1
谢谢,这解决了我的问题。微软需要看一下这个 bug。 - Samuel Moshie
1
我已经尝试了这段代码,但第一次尝试返回了null,但第二次尝试正常工作。 - undefined

1
我也想为此做出贡献。最近我刚刚解决了这个问题。我遇到了GetExternalLoginInfoAsync返回null的问题,但只在生产环境中出现。
经过大量搜索,我终于找到了答案,它只是我的数据库出了问题。在生产环境中,我设置了错误的连接字符串,所以它无法正确连接,但基本上没有任何提示。唯一发生的事情就是GetExternalLoginInfoAsync返回null。因此,如果发生这种情况,请检查您的数据库连接字符串!
此外,另一个需要注意的是,使其正常工作所需的唯一事项是:
  • 在Google控制台中设置项目
  • 启用Google+ API
  • 将客户端ID和客户端密钥复制到Startup.Auth.cs文件中。
您不必启用HTTPS,也不必创建自定义路由。但请确保您的数据库正常工作!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接