diff --git a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDFunctionalTest.php b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDFunctionalTest.php
index 71c6f02..c7fdf99 100644
--- a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDFunctionalTest.php
+++ b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDFunctionalTest.php
@@ -62,10 +62,14 @@ function testDiscovery() {
     // On HTTP test environments, the URL scheme is stripped in order to test
     // that the supplied identifier is normalized in openid_begin().
     $identity = url('openid-test/yadis/xrds', array('absolute' => TRUE));
-    $this->addIdentity(preg_replace('@^http://@', '', $identity), 2, 'http://example.com/xrds', $identity);
+    $this->addIdentity(preg_replace('@^http://@', '', $identity), 'http://example.com/xrds', $identity);
 
     $identity = url('openid-test/yadis/xrds/delegate', array('absolute' => TRUE));
-    $this->addIdentity(preg_replace('@^http://@', '', $identity), 2, 'http://example.com/xrds-delegate', $identity);
+    $this->addIdentity(preg_replace('@^http://@', '', $identity), 'http://example.com/xrds-delegate', $identity);
+
+    // Identifier is the URL of an XRDS document declaring an OpenID 1.x service.
+    $identity = url('openid-test/yadis/xrds/openid1', array('absolute' => TRUE));
+    $this->addIdentity(url('openid-test/yadis/xrds/openid1', array('absolute' => TRUE)), $identity);
 
     // Identifier is the URL of an XRDS document containing an OP Identifier
     // Element. The Relying Party sends the special value
@@ -76,26 +80,26 @@ function testDiscovery() {
     // Tell openid_test.module to respond with this identifier. If the fragment
     // part is present in the identifier, it should be retained.
     variable_set('openid_test_response', array('openid.claimed_id' => $identity));
-    $this->addIdentity(url('openid-test/yadis/xrds/server', array('absolute' => TRUE)), 2, 'http://specs.openid.net/auth/2.0/identifier_select', $identity);
+    $this->addIdentity(url('openid-test/yadis/xrds/server', array('absolute' => TRUE)), 'http://specs.openid.net/auth/2.0/identifier_select', $identity);
     variable_set('openid_test_response', array());
 
     // Identifier is the URL of an HTML page that is sent with an HTTP header
     // that contains the URL of an XRDS document.
-    $this->addIdentity(url('openid-test/yadis/x-xrds-location', array('absolute' => TRUE)), 2);
+    $this->addIdentity(url('openid-test/yadis/x-xrds-location', array('absolute' => TRUE)));
 
     // Identifier is the URL of an HTML page containing a <meta http-equiv=...>
     // element that contains the URL of an XRDS document.
-    $this->addIdentity(url('openid-test/yadis/http-equiv', array('absolute' => TRUE)), 2);
+    $this->addIdentity(url('openid-test/yadis/http-equiv', array('absolute' => TRUE)));
 
     // Identifier is an XRI. Resolve using our own dummy proxy resolver.
     config('openid.settings')
       ->set('xri_proxy_resolver', url('openid-test/yadis/xrds/xri', array('absolute' => TRUE)) . '/')
       ->save();
-    $this->addIdentity('@example*résumé;%25', 2, 'http://example.com/xrds', 'http://example.com/user');
+    $this->addIdentity('@example*résumé;%25', 'http://example.com/xrds', 'http://example.com/user');
 
     // Make sure that unverified CanonicalID are not trusted.
     variable_set('openid_test_canonical_id_status', 'bad value');
-    $this->addIdentity('@example*résumé;%25', 2, FALSE, FALSE);
+    $this->addIdentity('@example*résumé;%25', FALSE, FALSE);
 
     // HTML-based discovery:
     // If the User-supplied Identifier is a URL of an HTML page, the page may
@@ -103,10 +107,10 @@ function testDiscovery() {
     // Provider Endpoint. OpenID 1 and 2 describe slightly different formats.
 
     // OpenID Authentication 1.1, section 3.1:
-    $this->addIdentity(url('openid-test/html/openid1', array('absolute' => TRUE)), 1, 'http://example.com/html-openid1');
+    $this->addIdentity(url('openid-test/html/openid1', array('absolute' => TRUE)), 'http://example.com/html-openid1');
 
     // OpenID Authentication 2.0, section 7.3.3:
-    $this->addIdentity(url('openid-test/html/openid2', array('absolute' => TRUE)), 2, 'http://example.com/html-openid2');
+    $this->addIdentity(url('openid-test/html/openid2', array('absolute' => TRUE)), 'http://example.com/html-openid2');
 
     // OpenID Authentication 2.0, section 7.2.4:
     // URL Identifiers MUST then be further normalized by both (1) following
@@ -117,18 +121,18 @@ function testDiscovery() {
 
     // Single redirect.
     $identity = $expected_claimed_id = url('openid-test/redirected/yadis/xrds/1', array('absolute' => TRUE));
-    $this->addRedirectedIdentity($identity, 2, 'http://example.com/xrds', $expected_claimed_id, 0);
+    $this->addRedirectedIdentity($identity, 'http://example.com/xrds', $expected_claimed_id, 0);
 
     // Exact 3 redirects (default value for the 'max_redirects' option in
     // drupal_http_request()).
     $identity = $expected_claimed_id = url('openid-test/redirected/yadis/xrds/2', array('absolute' => TRUE));
-    $this->addRedirectedIdentity($identity, 2, 'http://example.com/xrds', $expected_claimed_id, 2);
+    $this->addRedirectedIdentity($identity, 'http://example.com/xrds', $expected_claimed_id, 2);
 
     // Fails because there are more than 3 redirects (default value for the
     // 'max_redirects' option in drupal_http_request()).
     $identity = url('openid-test/redirected/yadis/xrds/3', array('absolute' => TRUE));
     $expected_claimed_id = FALSE;
-    $this->addRedirectedIdentity($identity, 2, 'http://example.com/xrds', $expected_claimed_id, 3);
+    $this->addRedirectedIdentity($identity, 'http://example.com/xrds', $expected_claimed_id, 3);
   }
 
   /**
@@ -163,12 +167,6 @@ function testLogin() {
     $edit = array('openid_identifier' => $identity);
     $this->drupalPost('user/login/openid', $edit, t('Log in'));
 
-    // Check we are on the OpenID redirect form.
-    $this->assertTitle(t('OpenID redirect'), 'OpenID redirect page was displayed.');
-
-    // Submit form to the OpenID Provider Endpoint.
-    $this->drupalPost(NULL, array(), t('Send'));
-
     $this->assertLink(t('Log out'), 0, 'User was logged in.');
 
     // Verify user was redirected away from user/login/openid to an accessible
@@ -216,12 +214,6 @@ function testLoginMaintenanceMode() {
     $edit = array('openid_identifier' => $identity);
     $this->drupalPost('user/login/openid', $edit, t('Log in'));
 
-    // Check we are on the OpenID redirect form.
-    $this->assertTitle(t('OpenID redirect'), 'OpenID redirect page was displayed.');
-
-    // Submit form to the OpenID Provider Endpoint.
-    $this->drupalPost(NULL, array(), t('Send'));
-
     $this->assertLink(t('Log out'), 0, 'User was logged in.');
 
     // Verify user was redirected away from user/login/openid to an accessible
@@ -278,19 +270,44 @@ function testBlockedUserLogin() {
   }
 
   /**
+   * Test redirecting to the OpenID provider.
+   */
+  function testRedirect() {
+    // Verify that we fall back to POST using an auto-submitted form in OpenID
+    // 2.0, rather than generating URLs that are too long for Internet Explorer.
+    // We force a large request by adding a big dummy value to the request in
+    // hook_openid_request_alter() in openid_test module.
+    variable_set('openid_test_request_alter', array('checkid_setup' => array('openid.foo' => $this->randomName(2084))));
+
+    $identity = url('openid-test/yadis/xrds', array('absolute' => TRUE));
+    $this->submitLoginForm($identity);
+    $this->assertTitle(t('OpenID redirect'), 'OpenID redirect page was displayed.');
+    // Submit form to the OpenID Provider Endpoint. In real browsers, the form
+    // is auto-submitted via JavaScript.
+    $this->drupalPost(NULL, array(), t('Send'));
+    $this->assertRaw(t('Your OpenID'), 'Account creation page was displayed.');
+
+    // Verify that we do not send POST requests to OpenID 1.x providers.
+    $identity = url('openid-test/yadis/xrds/openid1', array('absolute' => TRUE));
+    $this->submitLoginForm($identity);
+    $this->assertNoTitle(t('OpenID redirect'), 'OpenID redirect page was not displayed.');
+    $headers = $this->drupalGetHeaders(TRUE);
+    $this->assert(strlen($headers[0]['location']) > 2084, 'Redirect to OpenID provider was a GET request.');
+    $this->assertRaw(t('Your OpenID'), 'Account creation page was displayed.');
+  }
+
+  /**
    * Add OpenID identity to user's profile.
    *
    * @param $identity
    *   The User-supplied Identifier.
-   * @param $version
-   *   The protocol version used by the service.
    * @param $local_id
    *   The expected OP-Local Identifier found during discovery.
    * @param $claimed_id
    *   The expected Claimed Identifier returned by the OpenID Provider, or FALSE
    *   if the discovery is expected to fail.
    */
-  function addIdentity($identity, $version = 2, $local_id = 'http://example.com/xrds', $claimed_id = NULL) {
+  function addIdentity($identity, $local_id = 'http://example.com/xrds', $claimed_id = NULL) {
     // Tell openid_test.module to only accept this OP-Local Identifier.
     variable_set('openid_test_identity', $local_id);
 
@@ -302,15 +319,6 @@ function addIdentity($identity, $version = 2, $local_id = 'http://example.com/xr
       return;
     }
 
-    // OpenID 1 used a HTTP redirect, OpenID 2 uses a HTML form that is submitted automatically using JavaScript.
-    if ($version == 2) {
-      // Check we are on the OpenID redirect form.
-      $this->assertTitle(t('OpenID redirect'), 'OpenID redirect page was displayed.');
-
-      // Submit form to the OpenID Provider Endpoint.
-      $this->drupalPost(NULL, array(), t('Send'));
-    }
-
     if (!isset($claimed_id)) {
       $claimed_id = $identity;
     }
@@ -327,8 +335,6 @@ function addIdentity($identity, $version = 2, $local_id = 'http://example.com/xr
    *
    * @param $identity
    *   The User-supplied Identifier.
-   * @param $version
-   *   The protocol version used by the service.
    * @param $local_id
    *   The expected OP-Local Identifier found during discovery.
    * @param $claimed_id
@@ -337,7 +343,7 @@ function addIdentity($identity, $version = 2, $local_id = 'http://example.com/xr
    * @param $redirects
    *   The number of redirects.
    */
-  function addRedirectedIdentity($identity, $version = 2, $local_id = 'http://example.com/xrds', $claimed_id = NULL, $redirects = 0) {
+  function addRedirectedIdentity($identity, $local_id = 'http://example.com/xrds', $claimed_id = NULL, $redirects = 0) {
     // Set the final destination URL which is the same as the Claimed
     // Identifier, we insert the same identifier also to the provider response,
     // but provider could further change the Claimed ID actually (e.g. it could
@@ -345,7 +351,7 @@ function addRedirectedIdentity($identity, $version = 2, $local_id = 'http://exam
     variable_set('openid_test_redirect_url', $identity);
     variable_set('openid_test_response', array('openid.claimed_id' => $identity));
 
-    $this->addIdentity(url('openid-test/redirect/' . $redirects, array('absolute' => TRUE)), $version, $local_id, $claimed_id);
+    $this->addIdentity(url('openid-test/redirect/' . $redirects, array('absolute' => TRUE)), $local_id, $claimed_id);
 
     // Clean up.
     variable_del('openid_test_redirect_url');
diff --git a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php
index f88ba92..accf68f 100644
--- a/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php
+++ b/core/modules/openid/lib/Drupal/openid/Tests/OpenIDTestBase.php
@@ -58,12 +58,6 @@ function submitLoginForm($identity) {
     // Fill out and submit the login form.
     $edit = array('openid_identifier' => $identity);
     $this->drupalPost('', $edit, t('Log in'), array(), array(), 'openid-login-form');
-
-    // Check we are on the OpenID redirect form.
-    $this->assertTitle(t('OpenID redirect'), 'OpenID redirect page was displayed.');
-
-    // Submit form to the OpenID Provider Endpoint.
-    $this->drupalPost(NULL, array(), t('Send'));
   }
 
   /**
diff --git a/core/modules/openid/openid.inc b/core/modules/openid/openid.inc
index 8d5aae9..fee01da 100644
--- a/core/modules/openid/openid.inc
+++ b/core/modules/openid/openid.inc
@@ -65,24 +65,32 @@
 const OPENID_NS_XRD = 'xri://$xrd*($v*2.0)';
 
 /**
- * Performs an HTTP 302 redirect (for the 1.x protocol).
+ * Redirects the user via an HTTP 302 redirect.
  */
-function openid_redirect_http($url, $message) {
-  $query = array();
-  foreach ($message as $key => $val) {
-    $query[] = $key . '=' . urlencode($val);
-  }
+function openid_redirect($url, $message, $force_get = FALSE) {
+  $redirect_url = $url . (strpos($url, '?') === FALSE ? '?' : '&') . http_build_query($message, '', '&');
 
-  $sep = (strpos($url, '?') === FALSE) ? '?' : '&';
-  header('Location: ' . $url . $sep . implode('&', $query), TRUE, 302);
+  $prefix_length = strlen(parse_url($url, PHP_URL_SCHEME) . '://' . parse_url($url, PHP_URL_HOST));
 
-  drupal_exit();
+  // Internet Explorer does not allow URLs longer than 2083 characters or paths
+  // longer than 2048 characters - see http://support.microsoft.com/kb/q208427.
+  // If the URL is longer, but the caller requested a GET, we try to redirect and
+  // hope for the best.
+  if ($force_get || (strlen($redirect_url) <= variable_get('openid_redirect_url_max_url_length', 2083) && strlen($redirect_url) - $prefix_length <= variable_get('openid_redirect_url_max_path_length', 2048))) {
+    header('Location: ' . $redirect_url, TRUE, 302);
+    drupal_exit();
+  }
+  else {
+    openid_redirect_post($url, $message);
+  }
 }
 
 /**
- * Creates a js auto-submit redirect for (for the 2.x protocol)
+ * Redirects the user by using JavaScript to auto-submit a form via POST.
+ *
+ * POST is not suppported in OpenID 1.x.
  */
-function openid_redirect($url, $message) {
+function openid_redirect_post($url, $message) {
   $language_interface = language(LANGUAGE_TYPE_INTERFACE);
 
   $output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' . "\n";
diff --git a/core/modules/openid/openid.module b/core/modules/openid/openid.module
index ada4933..9f61c87 100644
--- a/core/modules/openid/openid.module
+++ b/core/modules/openid/openid.module
@@ -376,11 +376,11 @@ function openid_begin($claimed_id, $return_to = '', $form_values = array()) {
   }
   $request = openid_authentication_request($claimed_id, $identity, $return_to, $assoc_handle, $service);
 
-  if ($service['version'] == 2) {
-    openid_redirect($service['uri'], $request);
+  if ($service['version'] == 1) {
+    openid_redirect($service['uri'], $request, TRUE);
   }
   else {
-    openid_redirect_http($service['uri'], $request);
+    openid_redirect($service['uri'], $request);
   }
 }
 
diff --git a/core/modules/openid/tests/openid_test.module b/core/modules/openid/tests/openid_test.module
index 5fe64cf..8af6eff 100644
--- a/core/modules/openid/tests/openid_test.module
+++ b/core/modules/openid/tests/openid_test.module
@@ -110,7 +110,17 @@ function openid_test_yadis_xrds() {
         <XRD>
           <Status cid="' . check_plain(variable_get('openid_test_canonical_id_status', 'verified')) . '"/>
           <ProviderID>xri://@</ProviderID>
-          <CanonicalID>http://example.com/user</CanonicalID>
+          <CanonicalID>http://example.com/user</CanonicalID>';
+
+    if (arg(3) == 'openid1') {
+      $output .= '
+          <Service priority="0">
+            <Type>http://openid.net/signon/1.0</Type>
+            <URI>' . url('openid-test/endpoint', array('absolute' => TRUE)) . '</URI>
+          </Service>';
+    }
+    else {
+      $output .= '
           <Service>
             <Type>http://example.com/this-is-ignored</Type>
           </Service>
@@ -133,6 +143,8 @@ function openid_test_yadis_xrds() {
             <URI>http://example.com/this-has-too-low-priority</URI>
           </Service>
           ';
+    }
+
     if (arg(3) == 'server') {
       $output .= '
           <Service>
