Merge pull request #444 from bobbyrullo/fix_375

Revert "Fix response_type missing param"
This commit is contained in:
bobbyrullo 2016-05-17 14:25:13 -07:00
commit e640be85c6
2 changed files with 43 additions and 98 deletions

View file

@ -255,7 +255,7 @@ func renderLoginPage(w http.ResponseWriter, r *http.Request, srv OIDCServer, idp
v := r.URL.Query() v := r.URL.Query()
v.Set("connector_id", idpc.ID()) v.Set("connector_id", idpc.ID())
v.Set("response_type", q.Get("response_type")) v.Set("response_type", "code")
link.URL = httpPathAuth + "?" + v.Encode() link.URL = httpPathAuth + "?" + v.Encode()
td.Links = append(td.Links, link) td.Links = append(td.Links, link)
} }
@ -273,92 +273,77 @@ func handleAuthFunc(srv OIDCServer, idpcs []connector.Connector, tpl *template.T
} }
q := r.URL.Query() q := r.URL.Query()
register := q.Get("register") == "1" && registrationEnabled
// Retrieve client id e := q.Get("error")
clientid := q.Get("client_id") if e != "" {
sessionKey := q.Get("state")
// Retrieve state if err := srv.KillSession(sessionKey); err != nil {
state := q.Get("state") log.Errorf("Failed killing sessionKey %q: %v", sessionKey, err)
}
// Retrieve response_type renderLoginPage(w, r, srv, idpcs, register, tpl)
responseType := q.Get("response_type")
// Retrieve scopes
qscope := strings.Fields(q.Get("scope"))
// Check client ID param
if clientid == "" {
log.Errorf("Invalid auth request: no client_id received")
writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), state)
return return
} }
// Check redirect_uri param, but if it's empty we don't return any error here connectorID := q.Get("connector_id")
qru := q.Get("redirect_uri") idpc, ok := idx[connectorID]
var rURL *url.URL if !ok {
if qru != "" { renderLoginPage(w, r, srv, idpcs, register, tpl)
ru, err := url.Parse(qru) return
if err != nil {
log.Errorf("Invalid auth request: %v", err)
writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), state)
return
}
rURL = ru
} }
cm, err := srv.ClientMetadata(clientid) acr, err := oauth2.ParseAuthCodeRequest(q)
if err != nil { if err != nil {
log.Errorf("Failed fetching client %q from repo: %v", clientid, err) log.Errorf("Invalid auth request: %v", err)
writeAuthError(w, oauth2.NewError(oauth2.ErrorServerError), state) writeAuthError(w, err, acr.State)
return
}
cm, err := srv.ClientMetadata(acr.ClientID)
if err != nil {
log.Errorf("Failed fetching client %q from repo: %v", acr.ClientID, err)
writeAuthError(w, oauth2.NewError(oauth2.ErrorServerError), acr.State)
return return
} }
if cm == nil { if cm == nil {
log.Errorf("Client %q not found", clientid) log.Errorf("Client %q not found", acr.ClientID)
writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), state) writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), acr.State)
return return
} }
if len(cm.RedirectURIs) == 0 { if len(cm.RedirectURIs) == 0 {
log.Errorf("Client %q has no redirect URLs", clientid) log.Errorf("Client %q has no redirect URLs", acr.ClientID)
writeAuthError(w, oauth2.NewError(oauth2.ErrorServerError), state) writeAuthError(w, oauth2.NewError(oauth2.ErrorServerError), acr.State)
return return
} }
redirectURL, err := client.ValidRedirectURL(rURL, cm.RedirectURIs) redirectURL, err := client.ValidRedirectURL(acr.RedirectURL, cm.RedirectURIs)
if err != nil { if err != nil {
switch err { switch err {
case (client.ErrorCantChooseRedirectURL): case (client.ErrorCantChooseRedirectURL):
log.Errorf("Request must provide redirect URL as client %q has registered many", clientid) log.Errorf("Request must provide redirect URL as client %q has registered many", acr.ClientID)
writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), state) writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), acr.State)
return return
case (client.ErrorInvalidRedirectURL): case (client.ErrorInvalidRedirectURL):
log.Errorf("Request provided unregistered redirect URL: %s", rURL) log.Errorf("Request provided unregistered redirect URL: %s", acr.RedirectURL)
writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), state) writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), acr.State)
return return
case (client.ErrorNoValidRedirectURLs): case (client.ErrorNoValidRedirectURLs):
log.Errorf("There are no registered URLs for the requested client: %s", rURL) log.Errorf("There are no registered URLs for the requested client: %s", acr.RedirectURL)
writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), state) writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), acr.State)
return
default:
log.Errorf("Unexpected error checking redirect URL for client %q: %v", clientid, err)
writeAuthError(w, oauth2.NewError(oauth2.ErrorServerError), state)
return return
} }
} }
// Response type check if acr.ResponseType != oauth2.ResponseTypeCode {
switch responseType { log.Errorf("unexpected ResponseType: %v: ", acr.ResponseType)
case "code": // Add more cases as we support more response types redirectAuthError(w, oauth2.NewError(oauth2.ErrorUnsupportedResponseType), acr.State, redirectURL)
default:
log.Errorf("Invalid auth request: unsupported response_type")
redirectAuthError(w, oauth2.NewError(oauth2.ErrorUnsupportedResponseType), state, redirectURL)
return return
} }
// Check scopes. // Check scopes.
var scopes []string var scopes []string
foundOpenIDScope := false foundOpenIDScope := false
for _, scope := range qscope { for _, scope := range acr.Scope {
switch scope { switch scope {
case "openid": case "openid":
foundOpenIDScope = true foundOpenIDScope = true
@ -379,33 +364,16 @@ func handleAuthFunc(srv OIDCServer, idpcs []connector.Connector, tpl *template.T
if !foundOpenIDScope { if !foundOpenIDScope {
log.Errorf("Invalid auth request: missing 'openid' in 'scope'") log.Errorf("Invalid auth request: missing 'openid' in 'scope'")
writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), state) writeAuthError(w, oauth2.NewError(oauth2.ErrorInvalidRequest), acr.State)
return
}
register := q.Get("register") == "1" && registrationEnabled
e := q.Get("error")
if e != "" {
if err := srv.KillSession(state); err != nil {
log.Errorf("Failed killing sessionKey %q: %v", state, err)
}
renderLoginPage(w, r, srv, idpcs, register, tpl)
return
}
connectorID := q.Get("connector_id")
idpc, ok := idx[connectorID]
if !ok {
renderLoginPage(w, r, srv, idpcs, register, tpl)
return return
} }
nonce := q.Get("nonce") nonce := q.Get("nonce")
key, err := srv.NewSession(connectorID, clientid, state, redirectURL, nonce, register, qscope) key, err := srv.NewSession(connectorID, acr.ClientID, acr.State, redirectURL, nonce, register, acr.Scope)
if err != nil { if err != nil {
log.Errorf("Error creating new session: %v: ", err) log.Errorf("Error creating new session: %v: ", err)
redirectAuthError(w, err, state, redirectURL) redirectAuthError(w, err, acr.State, redirectURL)
return return
} }
@ -431,7 +399,7 @@ func handleAuthFunc(srv OIDCServer, idpcs []connector.Connector, tpl *template.T
lu, err := idpc.LoginURL(key, p) lu, err := idpc.LoginURL(key, p)
if err != nil { if err != nil {
log.Errorf("Connector.LoginURL failed: %v", err) log.Errorf("Connector.LoginURL failed: %v", err)
redirectAuthError(w, err, state, redirectURL) redirectAuthError(w, err, acr.State, redirectURL)
return return
} }

View file

@ -175,29 +175,6 @@ func TestHandleAuthFuncResponsesSingleRedirectURL(t *testing.T) {
}, },
wantCode: http.StatusBadRequest, wantCode: http.StatusBadRequest,
}, },
// empty response_type
{
query: url.Values{
"redirect_uri": []string{"http://client.example.com/callback"},
"client_id": []string{"XXX"},
"connector_id": []string{"fake"},
"scope": []string{"openid"},
},
wantCode: http.StatusFound,
wantLocation: "http://client.example.com/callback?error=unsupported_response_type&state=",
},
// empty client_id
{
query: url.Values{
"response_type": []string{"code"},
"redirect_uri": []string{"http://unrecognized.example.com/callback"},
"connector_id": []string{"fake"},
"scope": []string{"openid"},
},
wantCode: http.StatusBadRequest,
},
} }
for i, tt := range tests { for i, tt := range tests {