ASP.NET MVC5 OWIN Facebook 身份验证突然不起作用

2023-11-28

2017年更新!

我发布原始问题时遇到的问题与 Facebook 最近强制每个人使用其 API 2.3 版本时所做的更改无关。有关该特定问题的解决方案,请参阅下面是 sammy34 的回答。 /oauth/access_token 端点的 2.3 版现在返回 JSON 而不是表单编码值

由于历史原因,这是我最初的问题/问题:

我有一个 MVC5 Web 应用程序,它使用通过 Facebook 和 Google 进行身份验证的内置支持。几个月前,当我们构建这个应用程序时,我们遵循了本教程:http://www.asp.net/mvc/tutorials/mvc-5/create-an-aspnet-mvc-5-app-with-facebook-and-google-oauth2-and-openid-sign-on一切都很好。

现在,突然间,Facebook 身份验证完全停止工作了。谷歌身份验证仍然很好用。

问题描述:我们单击链接使用 Facebook 进行连接,我们会被重定向到 Facebook,如果我们不允许 Facebook 应用程序访问我们的个人资料,系统会提示我们。当我们单击“确定”时,我们将被重定向回我们的网站,但我们并没有登录,而是直接到达登录屏幕。

我已经在调试模式下完成了这个过程,并且按照上面提到的教程,我在我的帐户控制器中得到了这个 ActionResult:

// GET: /Account/ExternalLoginCallback
[AllowAnonymous]
public async Task<ActionResult> ExternalLoginCallback(string returnUrl)
{
    var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
    if (loginInfo == null)
    {
        return RedirectToAction("Login");
    }
    ............

单步执行代码并从 Facebook 返回时,loginInfo 对象始终为 NULL,这会导致用户重定向回登录名。

为了了解幕后实际发生的情况,我安装了 Fiddler 并监控 HTTP 流量。我发现,在 Facebook 权限对话框中单击“确定”后,Facebook 会使用以下 URL 重定向回我们的应用程序:

https://localhost/signin-facebook?code=<access-token>

我猜这个 URL 不是一个实际的文件,可能是由内置于这个 OWIN 框架中的一些控制器/处理程序处理的。最有可能的是,它正在使用给定的代码连接回 Facebook,以查询有关尝试登录的用户的信息。现在的问题是,我们没有这样做,而是被重定向到:

/Account/ExternalLoginCallback?error=access_denied

我确信 Facebook 正在做的事情,即它没有向我们提供用户数据,而是使用此错误消息将我们重定向回来。

这导致AuthenticationManager.GetExternalLoginInfoAsync();失败并始终返回 NULL。

我完全没有主意了。据我们所知,我们最终没有改变任何东西。

我尝试过创建一个新的 Facebook 应用程序,我尝试再次按照教程进行操作,但我总是遇到同样的问题。

欢迎任何想法!

Update!

好吧,这让我发疯了!我现在已经手动完成了执行身份验证所需的步骤,并且当我这样做时一切都很好。为什么在使用 MVC5 Owin 东西时这不起作用?

这就是我所做的:

    // Step 1 - Pasted this into a browser, this returns a code
    https://www.facebook.com/dialog/oauth?response_type=code&client_id=619359858118523&redirect_uri=https%3A%2F%2Flocalhost%2Fsignin-facebook&scope=&state=u9R1m4iRI6Td4yACEgO99ETQw9NAos06bZWilJxJrXRn1rh4KEQhfuEVAq52UPnUif-lEHgayyWrsrdlW6t3ghLD8iFGX5S2iUBHotyTqCCQ9lx2Nl091pHPIw1N0JV23sc4wYfOs2YU5smyw9MGhcEuinvTAEql2QhBowR62FfU6PY4lA6m8pD3odI5MwBYOMor3eMLu2qnpEk0GekbtTVWgQnKnH6t1UcC6KcNXYY

I was redirected back to localhost (which I had shut down at this point to avoid being redirected immediately away).  The URL I was redirected to is this:

https://localhost/signin-facebook?code=<code-received-removed-for-obvious-reasons>

Now, I grabbed the code I got and used it in the URL below:

// Step 2 - opened this URL in a browser, and successfully retrieved an access token
https://graph.facebook.com/oauth/access_token?client_id=619359858118523&redirect_uri=https://localhost/signin-facebook&client_secret=<client-secret>&code=<code-from-step-1>

// Step 3 - Now I'm able to query the facebook graph using the access token from step 2!

https://graph.facebook.com/me?access_token=<access-token-from-step-2>

没有错误,一切都很好!那么为什么在使用 MVC5 Owin 东西时这不起作用呢? OWin 的实现显然有问题。


2017 年 4 月 22 日更新:Microsoft.Owin.* 软件包的 3.1.0 版现已推出。如果自 2017 年 3 月 27 日起 Facebook 的 API 更改后您遇到问题,请先尝试更新的 NuGet 包。就我而言,他们解决了问题(在我们的生产系统上运行良好)。

原答案:

就我而言,我于 2017 年 3 月 28 日醒来,发现我们应用程序的 Facebook 身份验证突然停止工作。我们没有更改应用程序代码中的任何内容。

事实证明,Facebook 在 2017 年 3 月 27 日对其图形 API 从版本 2.2 进行了“强制升级”至 2.3。这些版本的 API 的差异之一似乎是 Facebook 端点/oauth/access_token不再使用表单编码的内容主体进行响应,而是使用 JSON 进行响应。

现在,在Owin中间件中,我们找到了方法protected override FacebookAuthenticationHandler.AuthenticateCoreAsync(),它将响应的正文解析为表单,然后使用access_token从解析的形式。不用说,解析后的形式是空的,所以access_token也为空,导致access_denied错误在链的下游。

为了快速解决这个问题,我们为 Facebook Oauth 响应创建了一个包装类

public class FacebookOauthResponse
{
    public string access_token { get; set; }
    public string token_type { get; set; }
    public int expires_in { get; set; }
}

然后,在 OwinStart 中,我们添加了一个自定义反向通道处理程序...

        app.UseFacebookAuthentication(new FacebookAuthenticationOptions
        {
            AppId = "hidden",
            AppSecret = "hidden",
            BackchannelHttpHandler = new FacebookBackChannelHandler()
        });

...其中处理程序定义为:

public class FacebookBackChannelHandler : HttpClientHandler
{
    protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
    {
        var result = await base.SendAsync(request, cancellationToken);
        if (!request.RequestUri.AbsolutePath.Contains("access_token"))
            return result;

        // For the access token we need to now deal with the fact that the response is now in JSON format, not form values. Owin looks for form values.
        var content = await result.Content.ReadAsStringAsync();
        var facebookOauthResponse = JsonConvert.DeserializeObject<FacebookOauthResponse>(content);

        var outgoingQueryString = HttpUtility.ParseQueryString(string.Empty);
        outgoingQueryString.Add(nameof(facebookOauthResponse.access_token), facebookOauthResponse.access_token);
        outgoingQueryString.Add(nameof(facebookOauthResponse.expires_in), facebookOauthResponse.expires_in + string.Empty);
        outgoingQueryString.Add(nameof(facebookOauthResponse.token_type), facebookOauthResponse.token_type);
        var postdata = outgoingQueryString.ToString();

        var modifiedResult = new HttpResponseMessage(HttpStatusCode.OK)
        {
            Content = new StringContent(postdata)
        };

        return modifiedResult;
    }
}

基本上,处理程序只是创建一个新的 HttpResponseMessage,其中包含来自 Facebook JSON 响应的等效表单编码信息。请注意,此代码使用流行的 Json.Net 包。

有了这个自定义处理程序,问题似乎得到了解决(尽管我们还没有部署到产品:))。

希望这可以帮助其他人今天醒来时遇到类似的问题!

另外,如果有人对此有更干净的解决方案,我很想知道!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASP.NET MVC5 OWIN Facebook 身份验证突然不起作用 的相关文章

  • Facebook 分享链接 - 可以自定义消息正文吗?

    我正在尝试创建一个在 Facebook 上共享页面的链接 到目前为止我已经得到 href http www facebook com sharer php u http 3A 2F 2Fwww cnn com 2F t CNN 26s we
  • 一旦元素存在就触发事件的脚本?

    我正在尝试编写一个小 Greasemonkey 脚本来实现 Facebook 中的一些任务 例如隐藏新闻等 问题是 我有一个 DOM 中尚不存在的元素的 ID 这是点击帖子的箭头图标时出现的小框 如何通过 jQuery 创建一个事件处理程序
  • 如何在 ASP.NET 中注销 Facebook 连接?

    当用户通过 facebook connect 连接时 我无法注销该用户 我正在使用 Facebook 开发者工具包 有人知道如何 断开 用户吗 有注销用户的功能 FB Connect logout and FB Connect logout
  • Parse.com PFUser 链接 Twitter 和 Facebook 帐户?

    我在用parse com作为我的应用程序的后端 它使用户能够通过他的 Facebook 或 Twitter 帐户登录 它还具有将 Twitter Facebook 链接到他预先存在的帐户的功能 问题是这样的 如果用户通过他的facebook
  • 来自外部文件的 PHP 变量?

    编辑 完成的解决方案 工作代码 所以 这是我的一个朋友帮我想出来的 这是我在 K2 items php 文件中使用的部分 div class fb comments div
  • 如何在图谱API中获取永久访问令牌

    我在 Facebook 上创建了一个应用程序 并使用图形 API 资源管理器 从应用程序下拉框中选择了我的应用程序 请求了具有管理页面 离线访问和发布流权限的访问令牌 使用此访问令牌 我成功地能够使用以下方式在页面上发布消息restfbAP
  • Android:无法找到 com.facebook.wakizashi.provider.PlatformProvider 的提供商信息

    我现在被困了好几天了 我正在 facebook 中使用 PhotoShareDialogBu ilder 我使用了这样的内容提供程序
  • Facebook Unity Sdk v5.0.3 尝试登录时在横向模式下崩溃 - Android

    当我在横向模式下单击登录按钮时 游戏崩溃 如果我使用纵向模式 一切都会正常工作 当我崩溃时 我从 bugsense 得到了以下堆栈跟踪 java lang RuntimeException Unable to start activity
  • 如何让付费版和免费版iOS应用共享FB App ID?

    我有同一个 iPhone 应用程序的免费版和付费版 我希望他们共享一个 Facebook 应用程序 ID 因为它们本质上是同一个应用程序 我认为我可以通过使用 Facebook 类中的这个方法来完成此任务 void authorize NS
  • 未经授权访问用户 Facebook ID?

    我有一个本机 FBML Facebook 应用程序 我不想让应用程序访问者完成授权过程 但我确实想知道他们的 Facebook ID 是否可以找到访问用户的 Facebook ID 而不要求他们 授权 我的应用程序 之前 我说过这是不可能的
  • FB API 调用中“无法代表此用户调用 API”

    我在调用 facebook API 时遇到问题 我正在使用 Koala 进行服务器端 api 调用 但最近在进 行 api 调用时遇到问题 所以我尝试绕过 koala 调用并使用 call 进行原始 api http 调用 但无济于事 当我
  • 在 AccountController 外部访问 UserManager

    我正在尝试设置一列的值aspnetuser来自不同控制器的表 不是accountcontroller 我一直在尝试访问UserManager但我不知道我们该怎么做 到目前为止 我已经在我想使用它的控制器中尝试了以下操作 Applicatio
  • 剃刀 2 到剃刀 3 MVC 5

    我一直在开发 MVC 4 解决方案 并且一直在尝试将其升级到 MVC 5 我已按照概述的步骤操作here http www asp net mvc tutorials mvc 5 how to upgrade an aspnet mvc 4
  • Android 和 Facebook 共享意图

    我正在开发一个 Android 应用程序 并且有兴趣了解如何使用 Android 的共享意图在应用程序内更新应用程序用户的状态 浏览过 Facebook 的 SDK 后 这似乎很容易做到 但是我很想允许用户通过常规的共享意图弹出窗口来做到这
  • WebApi 2 和 MVC 5 使用不同的路由属性吗?

    通读this http blogs msdn com b webdev archive 2013 10 17 attribute routing in asp net mvc 5 aspx有关 ASP NET MVC 5 中的属性路由的博客
  • 如何以编程方式将图片上传到 Facebook?

    好的 这是我的第一个问题 如何允许我网站上的访问者在他们的 Facebook 新闻源上分享我的照片 https webapps stackexchange com questions 10140 how do i allow visitor
  • 是否可以更改 Facebook Connect 网站的范围?

    我正在构建一个 Facebook 应用程序 通过 Oauth 2 0 登录 Facebook 将来当我们添加功能时是否可以向用户请求更多权限 范围 或者我们是否需要预先请求所有权限 有人用 Facebook Connect 实现过这个吗 根
  • 如何从 Web API 应用程序返回 PDF

    我有一个在服务器上运行的 Web API 项目 它应该从两种不同类型的源返回 PDF 实际的可移植文档文件 PDF 和存储在数据库中的 base64 字符串 我遇到的问题是将文档发送回客户端 MVC 应用程序 剩下的部分是关于所发生的一切以
  • 在 React Native 中调试应用程序崩溃

    我是 React Native 新手 我正在尝试安装 React Native Facebook SDK 以便我可以使用我的应用程序进行 Facebook 登录 我按照此处列出的步骤操作 https tylermcginnis com in
  • Javascript split 不是一个函数

    嘿朋友们 我正在使用 javascript sdk 通过 jQuery facebook 多朋友选择器在用户朋友墙上发布信息 但是我收到此错误friendId split 不是函数 这是我的代码 function recommendToFr

随机推荐