关于重定向:为什么在OpenID 2中使用HTML表单重定向?

关于重定向:为什么在OpenID 2中使用HTML表单重定向?

Why is HTML form redirection used in OpenID 2?

为什么要执行自动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标准的一种解决方法,因此,只要双方都同意,则不应将其作为标准,而应将其作为替代实现。


    推荐阅读