Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: write authorize error returns 303 for get method #724

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
8 changes: 7 additions & 1 deletion authorize_error.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,5 +83,11 @@ func (f *Fosite) WriteAuthorizeError(ctx context.Context, rw http.ResponseWriter
}

rw.Header().Set("Location", redirectURIString)
rw.WriteHeader(http.StatusSeeOther)

switch ar.GetRequestMethod() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should add a comment explaining and linking why is this necessary.

case http.MethodGet:
rw.WriteHeader(http.StatusFound)
default:
rw.WriteHeader(http.StatusSeeOther)
}
}
46 changes: 31 additions & 15 deletions authorize_error_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"}))
req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -117,6 +118,7 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"}))
req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
req.EXPECT().GetRequestMethod().Return(http.MethodPost)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
},
checkHeader: func(t *testing.T, k int) {
Expand All @@ -138,7 +140,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"}))
req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -158,7 +161,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"}))
req.EXPECT().GetResponseMode().Return(ResponseModeDefault).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -178,7 +182,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code"}))
req.EXPECT().GetResponseMode().Return(ResponseModeQuery).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/?error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&foo=bar&state=foostate")
Expand All @@ -198,7 +203,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"foobar"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/?foo=bar#error=unsupported_grant_type&error_description=The+authorization+grant+type+is+not+supported+by+the+authorization+server.&state=foostate")
Expand All @@ -218,7 +224,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"token"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -238,7 +245,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"token"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -258,7 +266,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -279,7 +288,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -301,7 +311,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.+with-debug&state=foostate")
Expand All @@ -324,7 +335,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.+Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -347,7 +359,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -368,7 +381,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"code", "token"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -389,7 +403,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"id_token"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand All @@ -410,7 +425,8 @@ func TestWriteAuthorizeError(t *testing.T) {
req.EXPECT().GetResponseTypes().AnyTimes().Return(Arguments([]string{"token"}))
req.EXPECT().GetResponseMode().Return(ResponseModeFragment).AnyTimes()
rw.EXPECT().Header().Times(3).Return(header)
rw.EXPECT().WriteHeader(http.StatusSeeOther)
req.EXPECT().GetRequestMethod().Return(http.MethodGet)
rw.EXPECT().WriteHeader(http.StatusFound)
},
checkHeader: func(t *testing.T, k int) {
a, _ := url.Parse("https://foobar.com/?foo=bar#error=invalid_request&error_debug=with-debug&error_description=The+request+is+missing+a+required+parameter%2C+includes+an+invalid+parameter+value%2C+includes+a+parameter+more+than+once%2C+or+is+otherwise+malformed.&error_hint=Make+sure+that+the+various+parameters+are+correct%2C+be+aware+of+case+sensitivity+and+trim+your+parameters.+Make+sure+that+the+client+you+are+using+has+exactly+whitelisted+the+redirect_uri+you+specified.&state=foostate")
Expand Down
5 changes: 5 additions & 0 deletions authorize_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type AuthorizeRequest struct {
HandledResponseTypes Arguments `json:"handledResponseTypes" gorethink:"handledResponseTypes"`
ResponseMode ResponseModeType `json:"ResponseModes" gorethink:"ResponseModes"`
DefaultResponseMode ResponseModeType `json:"DefaultResponseMode" gorethink:"DefaultResponseMode"`
RequestMethod string `json:"requestMethod" gorethink:"requestMethod"`

Request
}
Expand Down Expand Up @@ -114,3 +115,7 @@ func (d *AuthorizeRequest) SetDefaultResponseMode(defaultResponseMode ResponseMo
func (d *AuthorizeRequest) GetDefaultResponseMode() ResponseModeType {
return d.DefaultResponseMode
}

func (d *AuthorizeRequest) GetRequestMethod() string {
return d.RequestMethod
}
3 changes: 3 additions & 0 deletions authorize_request_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,9 @@ func (f *Fosite) newAuthorizeRequest(ctx context.Context, r *http.Request, isPAR
// Save state to the request to be returned in error conditions (https://github.com/ory/hydra/issues/1642)
request.State = request.Form.Get("state")

// Save the original request method in order to use in later potions of the flow.
request.RequestMethod = r.Method

// Check if this is a continuation from a pushed authorization request
if !isPARRequest {
if isPAR, err := f.authorizeRequestFromPAR(ctx, r, request); err != nil {
Expand Down
14 changes: 14 additions & 0 deletions internal/authorize_request.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions oauth2.go
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,9 @@ type AuthorizeRequester interface {
// GetDefaultResponseMode gets default response mode for a response type in a flow
GetDefaultResponseMode() ResponseModeType

// GetRequestMethod returns the authorize requests HTTP method.
GetRequestMethod() string

Requester
}

Expand Down