diff --git a/httpsso/handler.go b/httpsso/handler.go
index 93f37302ad847177c7a0df12a6f112d3347825fd..6161905d52ff9bd1acf1be5b0ce03ef287b065a4 100644
--- a/httpsso/handler.go
+++ b/httpsso/handler.go
@@ -93,8 +93,8 @@ func (s *SSOWrapper) Wrap(h http.Handler, service string, groups []string) http.
 }
 
 func (s *SSOWrapper) handleLogin(w http.ResponseWriter, req *http.Request, session *sessions.Session, service string, groups []string) {
-	t := req.FormValue("t")
-	d := req.FormValue("d")
+	t := req.URL.Query().Get("t")
+	d := req.URL.Query().Get("d")
 
 	// Pop the nonce from the session.
 	nonce, ok := session.Values["nonce"].(string)
@@ -122,7 +122,7 @@ func (s *SSOWrapper) handleLogin(w http.ResponseWriter, req *http.Request, sessi
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	http.Redirect(w, req, d, http.StatusFound)
+	httputil.Redirect(w, req, d)
 }
 
 func (s *SSOWrapper) handleLogout(w http.ResponseWriter, req *http.Request, session *sessions.Session) {
@@ -156,7 +156,7 @@ func (s *SSOWrapper) redirectToLogin(w http.ResponseWriter, req *http.Request, s
 	v.Set("n", nonce)
 	v.Set("g", strings.Join(groups, ","))
 	loginURL := s.serverURL + "?" + v.Encode()
-	http.Redirect(w, req, loginURL, http.StatusFound)
+	httputil.Redirect(w, req, loginURL)
 }
 
 // Extract the URL path from the service specification. The result
diff --git a/httputil/redirect.go b/httputil/redirect.go
new file mode 100644
index 0000000000000000000000000000000000000000..b720feb0c91f8a833084ea4a05f628be87bb7f6c
--- /dev/null
+++ b/httputil/redirect.go
@@ -0,0 +1,14 @@
+package httputil
+
+import "net/http"
+
+// A http.Redirect wrapper that picks the redirect status code based
+// on the capabilities of the client (302 for HTTP/1.0, 307 for
+// HTTP/1.1).
+func Redirect(w http.ResponseWriter, req *http.Request, dest string) {
+	status := http.StatusTemporaryRedirect
+	if req.ProtoMajor == 0 || (req.ProtoMajor == 1 && req.ProtoMinor == 0) {
+		status = http.StatusFound
+	}
+	http.Redirect(w, req, dest, status)
+}
diff --git a/server/http.go b/server/http.go
index 6161cb29d5c9db4f6835b42502cf96bcfef5e64e..763b10530fcfae35172cc0aaaa16531441755e3d 100644
--- a/server/http.go
+++ b/server/http.go
@@ -321,7 +321,7 @@ func (h *Server) handleHomepage(w http.ResponseWriter, req *http.Request, sessio
 
 	// Redirect to service callback.
 	callbackURL := serviceLoginCallback(service, destination, token)
-	http.Redirect(w, req, callbackURL, http.StatusFound)
+	httputil.Redirect(w, req, callbackURL)
 }
 
 func (h *Server) alreadyLoggedOut(w http.ResponseWriter, req *http.Request) {
diff --git a/server/http_test.go b/server/http_test.go
index fa711be8dccb80b968a7b2fa1a7895541d097b56..78a4da9d6ae4571c22dc2708d2168e003cd71f88 100644
--- a/server/http_test.go
+++ b/server/http_test.go
@@ -135,8 +135,8 @@ func checkStatusOk(t testing.TB, resp *http.Response) {
 }
 
 func checkRedirectToTargetService(t testing.TB, resp *http.Response) {
-	if resp.StatusCode != 302 {
-		t.Fatalf("expected status 302, got %s", resp.Status)
+	if resp.StatusCode != 307 {
+		t.Fatalf("expected status 307, got %s", resp.Status)
 	}
 	if !strings.HasPrefix(resp.Header.Get("Location"), "https://service.example.com/sso_login?") {
 		t.Fatalf("redirect is not to target service: %v", resp.Header.Get("Location"))