Skip to content
This repository has been archived by the owner on Dec 7, 2020. It is now read-only.

Use HTTP 303 for redirects, instead HTTP 307 #628

Merged
merged 1 commit into from
Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,6 @@ type Config struct {
// EncryptionKey is the encryption key used to encrypt the refresh token
EncryptionKey string `json:"encryption-key" yaml:"encryption-key" usage:"encryption key used to encryption the session state" env:"ENCRYPTION_KEY"`

// InvalidAuthRedirectsWith303 will make requests with invalid auth headers redirect using HTTP 303 instead of HTTP 307. See github.com/keycloak/keycloak-gatekeeper/issues/292 for context.
InvalidAuthRedirectsWith303 bool `json:"invalid-auth-redirects-with-303" yaml:"invalid-auth-redirects-with-303" usage:"use HTTP 303 redirects instead of 307 for invalid auth tokens"`
// NoRedirects informs we should hand back a 401 not a redirect
NoRedirects bool `json:"no-redirects" yaml:"no-redirects" usage:"do not have back redirects when no authentication is present, 401 them"`
// SkipTokenVerification tells the service to skipp verifying the access token - for testing purposes
Expand Down
8 changes: 4 additions & 4 deletions handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ func (r *oauthProxy) oauthAuthorizationHandler(w http.ResponseWriter, req *http.
return
}

r.redirectToURL(authURL, w, req, http.StatusTemporaryRedirect)
r.redirectToURL(authURL, w, req, http.StatusSeeOther)
}

// getClientAuthMethod maps the config value CLIENT_AUTH_METHOD to valid OAuth2 auth method keys
Expand Down Expand Up @@ -229,7 +229,7 @@ func (r *oauthProxy) oauthCallbackHandler(w http.ResponseWriter, req *http.Reque
}
}

r.redirectToURL(redirectURI, w, req, http.StatusTemporaryRedirect)
r.redirectToURL(redirectURI, w, req, http.StatusSeeOther)
}

// loginHandler provide's a generic endpoint for clients to perform a user_credentials login to the provider
Expand Down Expand Up @@ -359,7 +359,7 @@ func (r *oauthProxy) logoutHandler(w http.ResponseWriter, req *http.Request) {
}
}

r.redirectToURL(fmt.Sprintf("%s?redirect_uri=%s", sendTo, url.QueryEscape(redirectURL)), w, req, http.StatusTemporaryRedirect)
r.redirectToURL(fmt.Sprintf("%s?redirect_uri=%s", sendTo, url.QueryEscape(redirectURL)), w, req, http.StatusSeeOther)

return
}
Expand Down Expand Up @@ -411,7 +411,7 @@ func (r *oauthProxy) logoutHandler(w http.ResponseWriter, req *http.Request) {
}
// step: should we redirect the user
if redirectURL != "" {
r.redirectToURL(redirectURL, w, req, http.StatusTemporaryRedirect)
r.redirectToURL(redirectURL, w, req, http.StatusSeeOther)
}
}

Expand Down
18 changes: 9 additions & 9 deletions handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ func TestLogoutHandlerGood(t *testing.T) {
{
URI: c.WithOAuthURI(logoutURL) + "?redirect=http://example.com",
HasToken: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
ExpectedLocation: "http://example.com",
},
}
Expand Down Expand Up @@ -220,7 +220,7 @@ func TestServiceRedirect(t *testing.T) {
{
URI: "/admin",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
ExpectedLocation: "/oauth/authorize?state",
},
{
Expand Down Expand Up @@ -248,25 +248,25 @@ func TestAuthorizationURL(t *testing.T) {
URI: "/admin",
Redirects: true,
ExpectedLocation: "/oauth/authorize?state",
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{
URI: "/admin/test",
Redirects: true,
ExpectedLocation: "/oauth/authorize?state",
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{
URI: "/help/../admin",
Redirects: true,
ExpectedLocation: "/oauth/authorize?state",
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{
URI: "/admin?test=yes&test1=test",
Redirects: true,
ExpectedLocation: "/oauth/authorize?state",
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{
URI: "/oauth/test",
Expand Down Expand Up @@ -298,19 +298,19 @@ func TestCallbackURL(t *testing.T) {
URI: cfg.WithOAuthURI(callbackURL) + "?code=fake",
ExpectedCookies: map[string]string{cfg.CookieAccessName: ""},
ExpectedLocation: "/",
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{
URI: cfg.WithOAuthURI(callbackURL) + "?code=fake&state=/admin",
ExpectedCookies: map[string]string{cfg.CookieAccessName: ""},
ExpectedLocation: "/",
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{
URI: cfg.WithOAuthURI(callbackURL) + "?code=fake&state=L2FkbWlu",
ExpectedCookies: map[string]string{cfg.CookieAccessName: ""},
ExpectedLocation: "/",
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
}
newFakeProxy(cfg).RunTests(t, requests)
Expand Down
26 changes: 13 additions & 13 deletions middleware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ func TestOauthRequests(t *testing.T) {
{
URI: "/oauth/authorize",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{
URI: "/oauth/callback",
Expand All @@ -379,7 +379,7 @@ func TestOauthRequestsWithBaseURI(t *testing.T) {
{
URI: "/base-uri/oauth/authorize",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{
URI: "/base-uri/oauth/callback",
Expand Down Expand Up @@ -614,22 +614,22 @@ func TestNoProxyingRequests(t *testing.T) {
{ // check for escaping
URI: "/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/etc/passwd",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{ // check for escaping
URI: "/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/.%2e/",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{ // check for escaping
URI: "/../%2e",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{ // check for escaping
URI: "",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
}
newFakeProxy(c).RunTests(t, requests)
Expand All @@ -650,27 +650,27 @@ func TestStrangeAdminRequests(t *testing.T) {
{ // check for escaping
URI: "//admin%2Ftest",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{ // check for escaping
URI: "///admin/../admin//%2Ftest",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{ // check for escaping
URI: "/admin%2Ftest",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{ // check for prefix slashs
URI: "/" + testAdminURI,
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{ // check for double slashs
URI: testAdminURI,
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{ // check for double slashs no redirects
URI: "/admin//test",
Expand All @@ -681,7 +681,7 @@ func TestStrangeAdminRequests(t *testing.T) {
{ // check for dodgy url
URI: "//admin/.." + testAdminURI,
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{ // check for it works
URI: "/" + testAdminURI,
Expand Down Expand Up @@ -942,7 +942,7 @@ func TestRolePermissionsMiddleware(t *testing.T) {
{ // check for redirect
URI: "/",
Redirects: true,
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
{ // check with a token but not test role
URI: "/",
Expand Down
6 changes: 1 addition & 5 deletions misc.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,7 @@ func (r *oauthProxy) redirectToAuthorization(w http.ResponseWriter, req *http.Re
w.WriteHeader(http.StatusForbidden)
return r.revokeProxy(w, req)
}
if r.config.InvalidAuthRedirectsWith303 {
r.redirectToURL(r.config.WithOAuthURI(authorizationURL+authQuery), w, req, http.StatusSeeOther)
} else {
r.redirectToURL(r.config.WithOAuthURI(authorizationURL+authQuery), w, req, http.StatusTemporaryRedirect)
}
r.redirectToURL(r.config.WithOAuthURI(authorizationURL+authQuery), w, req, http.StatusSeeOther)

return r.revokeProxy(w, req)
}
Expand Down
3 changes: 1 addition & 2 deletions misc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,15 +36,14 @@ func TestRedirectToAuthorization(t *testing.T) {
URI: "/admin",
Redirects: true,
ExpectedLocation: "/oauth/authorize?state",
ExpectedCode: http.StatusTemporaryRedirect,
ExpectedCode: http.StatusSeeOther,
},
}
newFakeProxy(nil).RunTests(t, requests)
}

func TestRedirectToAuthorizationWith303Enabled(t *testing.T) {
cfg := newFakeKeycloakConfig()
cfg.InvalidAuthRedirectsWith303 = true

requests := []fakeRequest{
{
Expand Down
2 changes: 1 addition & 1 deletion oauth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func (r *fakeAuthServer) authHandler(w http.ResponseWriter, req *http.Request) {
}
redirectionURL := fmt.Sprintf("%s?state=%s&code=%s", redirect, state, getRandomString(32))

http.Redirect(w, req, redirectionURL, http.StatusTemporaryRedirect)
http.Redirect(w, req, redirectionURL, http.StatusSeeOther)
}

func (r *fakeAuthServer) logoutHandler(w http.ResponseWriter, req *http.Request) {
Expand Down
2 changes: 1 addition & 1 deletion server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ func makeTestCodeFlowLogin(location string) (*http.Response, error) {
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusTemporaryRedirect {
if resp.StatusCode != http.StatusSeeOther {
return nil, errors.New("no redirection found in resp")
}
location = resp.Header.Get("Location")
Expand Down