为什么要执行自动HTML发布而不是简单的重定向?
这样是不是开发人员可以在已知OpenID时自动生成将目录发布到远程服务器的登录表单?
例如。
用户尚未登录并访问您的登录页面。
您从cookie中检测到用户的openID。
生成的表单直接发布到远程OpenID服务器。
远程服务器将用户重定向回网站。
网站登录用户。
如果是这样,我可以看到好处。但是,这假设您在用户注销时将用户的openID保留在cookie中。
我几乎找不到有关如何最好地实现此规范的信息。
请参阅官方规范中的HTML FORM重定向:
http://openid.net/specs/openid-authentication-2_0.html#indirect_comm
我通过查看PHP OpenID库(版本2.1.1)发现了这一点。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| // Redirect the user to the OpenID server for authentication.
// Store the token for this authentication so we can verify the
// response.
// For OpenID 1, send a redirect. For OpenID 2, use a Javascript
// form to send a POST request to the server.
if ($auth_request->shouldSendRedirect()) {
$redirect_url = $auth_request->redirectURL(getTrustRoot(),
getReturnTo());
// If the redirect URL can't be built, display an error
// message.
if (Auth_OpenID::isFailure($redirect_url)) {
displayError("Could not redirect to server:" . $redirect_url->message);
} else {
// Send redirect.
header("Location:".$redirect_url);
}
} else {
// Generate form markup and render it.
$form_id = 'openid_message';
$form_html = $auth_request->htmlMarkup(getTrustRoot(), getReturnTo(),
false, array('id' => $form_id));
// Display an error if the form markup couldn't be generated;
// otherwise, render the HTML.
if (Auth_OpenID::isFailure($form_html)) {
displayError("Could not redirect to server:" . $form_html->message);
} else {
print $form_html;
}
} |
我可以想到几个原因:
-
默默无闻的安全性-篡改POST提交要比GET花费更多的工作
-
缓存和重新提交规则对POST的限制比对GET的限制更大。不过,我不太确定这对于OpenID用例是否重要。
-
漫游器不会遵循POST表单,但会遵循重定向。这可能会影响服务器负载。
-
不同的浏览器对GET请求的最大长度有所不同-但它们都不像POST一样大。
-
某些浏览器会警告重定向到另一个域。如果您要向非HTTPS网址提交POST,他们也会警告您。
-
通过关闭JavaScript,我可以获得相对安全的体验,而不会被无提示地重定向到另一个域。
我不知道这些是选择POST的一个灌篮理由-除非发送的数据量超过某些主流浏览器的querystring长度。
正如Mark Brackett所说,主要动机是通过使用重定向和GET来限制有效负载大小。有些实现足够聪明,仅在消息超过一定大小时才使用POST,因为POST技术肯定有缺点。 (其中最重要的是您的"后退"按钮不起作用的事实。)其他实现(例如您引用的示例代码)则出于简单性和一致性的考虑,并省略了该条件。
SAML Web浏览器SSO配置文件使用相同的方法。使用HTML Post重定向的主要动机是:
-
有效负载的长度几乎是无限的:在SAML中,有效负载是一个XML文档,该文档使用XMLDSig和base64编码。它大于URL的通常1024个字符的限制(最佳实践不仅支持任何浏览器,而且还支持中间网络设备,例如防火墙,反向代理,负载平衡器)。
-
W3C HTTP标准说GET是幂等的(多次执行相同的URL GET应该总是产生相同的响应),因此可以沿途进行缓存,而POST则不行,并且必须到达URL目标。 OpenID HTML表单POST或SAML HTML表单POST的响应不应被缓存。它必须到达目标才能启动已认证的会话。
您可能会争辩说,使用HTTP GET重定向也可以正常工作,因为URL查询总是在变化,而实践是正确的。但是,这将是W3C标准的一种解决方法,因此,只要双方都同意,则不应将其作为标准,而应将其作为替代实现。