Fix SSO cookies not stored on Firefox 302 redirects
Firefox does not reliably store Set-Cookie headers on 302 responses that redirect to a different origin. Change RedirectToLogin to return a 200 with an HTML meta-refresh instead, ensuring cookies are stored before navigation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
17
sso/sso.go
17
sso/sso.go
@@ -22,6 +22,7 @@ import (
|
|||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"html"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
@@ -268,6 +269,12 @@ func ConsumeReturnToCookie(w http.ResponseWriter, r *http.Request, prefix string
|
|||||||
|
|
||||||
// RedirectToLogin generates a state, sets the state and return-to cookies,
|
// RedirectToLogin generates a state, sets the state and return-to cookies,
|
||||||
// and redirects the user to the MCIAS authorize URL.
|
// and redirects the user to the MCIAS authorize URL.
|
||||||
|
//
|
||||||
|
// The redirect is performed via a 200 response with an HTML meta-refresh
|
||||||
|
// instead of a 302. Some browsers (notably Firefox) do not reliably store
|
||||||
|
// Set-Cookie headers on 302 responses that redirect to a different origin,
|
||||||
|
// even when the origins are same-site. Using a 200 response ensures the
|
||||||
|
// cookies are stored before the browser navigates away.
|
||||||
func RedirectToLogin(w http.ResponseWriter, r *http.Request, client *Client, cookiePrefix string) error {
|
func RedirectToLogin(w http.ResponseWriter, r *http.Request, client *Client, cookiePrefix string) error {
|
||||||
state, err := GenerateState()
|
state, err := GenerateState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -276,7 +283,15 @@ func RedirectToLogin(w http.ResponseWriter, r *http.Request, client *Client, coo
|
|||||||
|
|
||||||
SetStateCookie(w, cookiePrefix, state)
|
SetStateCookie(w, cookiePrefix, state)
|
||||||
SetReturnToCookie(w, r, cookiePrefix)
|
SetReturnToCookie(w, r, cookiePrefix)
|
||||||
http.Redirect(w, r, client.AuthorizeURL(state), http.StatusFound)
|
|
||||||
|
authorizeURL := client.AuthorizeURL(state)
|
||||||
|
escaped := html.EscapeString(authorizeURL)
|
||||||
|
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
_, _ = fmt.Fprintf(w, `<!DOCTYPE html>
|
||||||
|
<html><head><meta http-equiv="refresh" content="0;url=%s"></head>
|
||||||
|
<body><p>Redirecting to <a href="%s">MCIAS</a>...</p></body></html>`,
|
||||||
|
escaped, escaped)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user