- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
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 身份验证完全停止工作。 Google 身份验证仍然有效。
问题描述:我们点击链接使用 Facebook 连接,我们被重定向到 Facebook,如果我们不想让我们的 Facebook 应用程序访问我们的个人资料,系统会提示我们。当我们单击“确定”时,我们将被重定向回我们的站点,但我们并没有登录,而是直接进入了登录屏幕。
我已经在 Debug模式下完成了这个过程,并且按照上面提到的教程,我在我的帐户 Controller 中得到了这个 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 框架中内置的一些 Controller /处理程序处理的。最有可能的是,它使用给定的代码连接回 Facebook,以查询有关尝试登录的用户的信息。现在,问题是我们没有这样做,而是被重定向到:
/Account/ExternalLoginCallback?error=access_denied
我敢肯定这是 Facebook 正在做的事情,也就是说,它没有向我们提供用户数据,而是使用此错误消息将我们重定向回去。
这会导致 AuthenticationManager.GetExternalLoginInfoAsync();
失败并始终返回 NULL。
我完全没有想法。据我们所知,我们并没有改变任何东西。
我尝试创建一个新的 Facebook 应用程序,我尝试再次按照教程操作,但我总是遇到同样的问题。
欢迎任何想法!
更新!
好吧,这让我发疯!我现在已经手动完成了执行身份验证所需的步骤,并且当我这样做时一切正常。为什么这在使用 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 版现已可用。如果您在 Facebook 的 API 从 2017 年 3 月 27 日起更改后遇到问题,请先尝试更新后的 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 中,我们添加了一个自定义的反向 channel 处理程序...
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 包。
有了这个自定义处理程序,问题似乎就解决了(虽然我们还没有部署到产品 :))。
希望这能拯救今天醒来时遇到类似问题的其他人!
此外,如果有人对此有更简洁的解决方案,我很想知道!
关于facebook - ASP.NET MVC5 OWIN Facebook 身份验证突然不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22364442/
我有一个我想暂时存储的对象。该对象现在在 Controller 中, Controller 将生成一个 View 。 AJAX 请求从 View 发送到下一个 Controller 。那一刻我需要先前
从MVC 2开始,我们可以轻松创建区域。现在,我的问题与嵌套区域(区域内部的区域)有关。 选择我的“father”区域文件夹,右键单击> Add> NO选项以获取new Area。 是否有可能以其他方
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 7年前关闭。 Improve thi
我已经尝试了一些谷歌搜索和堆栈流搜索,但事实证明这比我想象的要难找到。我需要为我们的商店迁移到 ASP.NET MVC 2 的管理提供理由。最大的帮助将是任何企业级站点或使用 ASP.NET MVC
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 6 年前。 Improv
我有一些常见的网页,它们将出现在多个 MVC 应用程序中。对于这些页面,我想在不同的 MVC 网站之间重用相同的源代码( Controller + View )。这样做的最佳方法是什么? ASP.NE
我正在使用 Spring MVC 来构建我的应用程序。 当用户在浏览器中运行应用程序时,我想显示一个默认的 jsp。我不想用 web.xml 中的标记。 我想我可以用 我已经创建了一个文件夹并添
我可能在这里分析过度了,但是根据我对 MVC 的阅读,似乎有很多关于如何做事情的观点。 是否有一个“最佳实践”网站或文档来定义 MVC 各个部分的职责? 请记住,我使用 EF/Repository&U
当杰里米和查德 posted about their FubuMvc project ,他们提到的差异化因素之一是他们的“雷霆穹顶校长”: The “Thunderdome Principle” –
我正在为 Spring MVC 应用程序实现缓存清除系统。 为了让这个系统正常工作,我必须从给定的 url 中删除“缓存破坏代码”。假设我生成的缓存破坏代码是“123”,我有一个 .css url:/
在调试 ASP.NET MVC 源时,我发现使用了“MVC-ControllerTypeCache.xml” 文件。但我无法理解这个文件的用途。我的意思是这个文件存储在哪里?asp.net MVc 如
我刚刚在我的本地机器上安装了 Visual Studio 11 和 MVC 4 beta。但是,每当我打开一个 MVC 3 项目(我想保留为 MVC 3)时,所有引用都已更新为版本 4 DLL。当然它
我有一个 MVC 3 应用程序,它具有一些核心功能(最重要的是自动化),但主要用作不同区域或模块的门户。我想将它组织到不同的模块中,只需稍作更改也可以部署为他们自己的网站。 该项目由论坛、博客引擎、用
我有自己的服务器,正在考虑将我的一个解决方案升级到 ASP.NET MVC 4,然后再升级其余的 (3+)。 作为其中的一部分,我下载了 the standalone installer对于 ASP.
构图 我有一个 MVC 项目,其中包含 C# 类,这些类最终通过 ajax 等进行序列化和使用。我使用 TypeLite 生成这些 C# 类的定义( here 讨论了 TypeLite 的替代方案),
我正在尝试了解现代 Web 应用程序架构。在 ASP.NET MVC 中,所有业务逻辑类都在 Model 中,Controller 接受并引导用户请求。如果我使用它,是否可以使用本身是 MVC 架构但
我有一个带有 OWIN 的 WebAPI 2 应用程序。现在我正在尝试向所有内容添加一个 MVC 5 Controller ,但没有找到我的 MVC 路由。我收到以下错误: No HTTP resou
在 MVC 3 中,他们添加了我一直在使用的依赖解析器。在回答某人对您发表评论的问题时,您应该使用 Ninject MVC 3 插件。 所以我的问题是为什么要使用它而不是内置的?如果这是要走的路,你如
我是 ASP.NET MVC 的新手,我正在寻找最不痛苦的方法来设置全局错误处理、日志记录和报告(通过电子邮件)。仅供引用,我的 ASP.NET MVC 应用程序在 Azure 中作为 Web 角色托
何时使用 MVC View 页面和 MVC View 内容页面?它们有什么区别? 最佳答案 **MVC View Page 用于创建页面,MVC VewP Content Page 用于创建页面并指定
我是一名优秀的程序员,十分优秀!