当您使用Web应用程序与Facebook登录集成时,您可以在Facebook上的应用程序设置中指定Web应用程序的URL。尝试在未从该URL加载的页面上使用该应用程序的ID会产生相应的错误:“应用程序配置不允许给定URL。”
他们如何做到这一点,而不是让它挫败琐碎?如果该应用已获得http://example-a.com
授权,如果我复制应用ID并尝试使用http://example-b.com
,它们如何阻止访问?我试图了解他们是如何做到这一点的,因为我需要在我正在做的一些工作中做一个类似锁定的URL。
我有一种强烈的意识,错过了这里显而易见的事实。
我知道他们正在使用授权/身份验证流程“based on”OAuth 2.0 spec(以及基本流程isn't exactly complicated),但我无法确定哪个阶段(s)在该流程中,他们验证了原始页面的URL以及他们如何将该URL发送到他们的服务,同时确保它没有被篡改/欺骗。
我(我想我已经)消除的事情:
虽然我看到它们在原始域中传递(在查询字符串等中),但它们不能仅仅依赖于它,修改调用代码以“调整”它是微不足道的。我希望解决方案的部分,但只是其中的一部分。
他们无法使用Referer
(原文如此)标题,因为欺骗是微不足道的。
他们不能使用(仅)在原始页面中运行的代码,因为可以对其进行修改。
他们不能只依靠postMessage
,因为Facebook登录适用于IE8 / 9,它是一个弹出窗口(不仅仅是一个框架); IE8 / 9 only works within frames中的postMessage
,而不是单独的标签/窗口。
答案 0 :(得分:1)
当我在问题中写下我的第四个要点时,我意识到他们可以做什么(并且检查了一些关于postMessage
的非常有用的东西。)
我认为他们大致是这样做的:
加载到原始页面的Facebook代码(当然可以被黑客攻击 - 但稍后处理)会将iframe
从mumble.facebook.com
添加到原始页面; iframe
包含“登录”按钮。
原始页面上的Facebook代码使用postMessage
与iframe
进行对话。
iframe
中的代码 - 原始网站无法合理破解,因为它是从mumble.facebook.com
加载的 - 使用它收到的事件对象的origin
属性来自原始页面的postMessage
条消息;这就是它如何拥有原始起源的可靠版本。这不能被欺骗(除了浏览器错误)。
iframe
中的“登录”按钮会打开一个弹出式窗口(从mumble.facebook.com
加载),使用opener
(但不是postMessage
)与{ {1}}(因为iframe
和弹出窗口是从同一个源加载的,所以它们可以这样做 - 而且由于IE8 / 9问题,它们必须而不是iframe
。
然后是互动:
+------------------+ +--------+ +-------+ | Originating page |<-->| iframe |<-->| popup |<------+ +------------------+ +--------+ +-------+ | ^ v | +---------------------+ +------------------>| mumble.facebook.com | +---------------------+
基本上,postMessage
是原始页面和弹出窗口(以及一般的Facebook)之间的代理,它位于Facebook的原始页面(发起页面和iframe
之间的通信)获得原始页面起源的可靠版本。
我相信他们将原始来源作为查询参数传递给iframe
作为附加度量; iframe
可能会将其用于发布回原始页面的任何消息,因此如果查询参数被黑客攻击,那么这些消息永远不会被原始页面接收,也无法正常工作。或者他们只是比较它们。
由于iframe
无法欺骗(禁止浏览器错误),event.origin
和弹出窗口的代码和标记来自iframe
,因此它相当安全可靠( “合理地”在Web浏览器领域内。)
答案 1 :(得分:0)
Nice Ascii图形: - )
我认为答案要简单得多,它适用于所有基于OAuth2的系统。请求授权的应用程序发送redirect_uri
参数,该参数必须与您在授权服务器(本例中为FB)中注册的任何内容相匹配。如果您发送的内容与注册值不符,则会被拒绝。我不相信他们检查推荐人或其他任何东西。如果查询参数匹配,则授权服务器将用户发送回redirect_uri
code
(并且OAuth2流程继续:使用代码获取令牌等)。
应用程序还应发送在整个事务中保留的
state
参数,并在返回时进行检查。