fix: encode auth response correctly (when using query in redirect uri)

This commit is contained in:
Livio Amstutz 2022-06-17 13:01:20 +02:00
parent f345ddd0c5
commit 9472f2a009
No known key found for this signature in database
GPG key ID: 26BB1C2FA5952CF0
2 changed files with 32 additions and 10 deletions

View file

@ -77,14 +77,13 @@ func HttpRequest(client *http.Client, req *http.Request, response interface{}) e
return nil return nil
} }
func URLEncodeResponse(resp interface{}, encoder Encoder) (string, error) { func URLEncodeParams(resp interface{}, encoder Encoder) (url.Values, error) {
values := make(map[string][]string) values := make(map[string][]string)
err := encoder.Encode(resp, values) err := encoder.Encode(resp, values)
if err != nil { if err != nil {
return "", err return nil, err
} }
v := url.Values(values) return values, nil
return v.Encode(), nil
} }
func StartServer(ctx context.Context, port string) { func StartServer(ctx context.Context, port string) {

View file

@ -464,18 +464,41 @@ func BuildAuthRequestCode(authReq AuthRequest, crypto Crypto) (string, error) {
//AuthResponseURL encodes the authorization response (successful and error) and sets it as query or fragment values //AuthResponseURL encodes the authorization response (successful and error) and sets it as query or fragment values
//depending on the response_mode and response_type //depending on the response_mode and response_type
func AuthResponseURL(redirectURI string, responseType oidc.ResponseType, responseMode oidc.ResponseMode, response interface{}, encoder httphelper.Encoder) (string, error) { func AuthResponseURL(redirectURI string, responseType oidc.ResponseType, responseMode oidc.ResponseMode, response interface{}, encoder httphelper.Encoder) (string, error) {
params, err := httphelper.URLEncodeResponse(response, encoder) uri, err := url.Parse(redirectURI)
if err != nil { if err != nil {
return "", oidc.ErrServerError().WithParent(err) return "", oidc.ErrServerError().WithParent(err)
} }
params, err := httphelper.URLEncodeParams(response, encoder)
if err != nil {
return "", oidc.ErrServerError().WithParent(err)
}
//return explicitly requested mode
if responseMode == oidc.ResponseModeQuery { if responseMode == oidc.ResponseModeQuery {
return redirectURI + "?" + params, nil return mergeQueryParams(uri, params), nil
} }
if responseMode == oidc.ResponseModeFragment { if responseMode == oidc.ResponseModeFragment {
return redirectURI + "#" + params, nil return setFragment(uri, params), nil
} }
if responseType == "" || responseType == oidc.ResponseTypeCode { //implicit must use fragment mode is not specified by client
return redirectURI + "?" + params, nil if responseType == oidc.ResponseTypeIDToken || responseType == oidc.ResponseTypeIDTokenOnly {
return setFragment(uri, params), nil
} }
return redirectURI + "#" + params, nil //if we get here it's code flow: defaults to query
return mergeQueryParams(uri, params), nil
}
func setFragment(uri *url.URL, params url.Values) string {
uri.Fragment = params.Encode()
return uri.String()
}
func mergeQueryParams(uri *url.URL, params url.Values) string {
queries := uri.Query()
for param, values := range params {
for _, value := range values {
queries.Set(param, value)
}
}
uri.RawQuery = queries.Encode()
return uri.String()
} }