diff --git a/server/handlers.go b/server/handlers.go index 6017b126f737a569b386600a3d3d0ac90fd06635..055c0b83918b5653f324d5ced892333a48326c29 100644 --- a/server/handlers.go +++ b/server/handlers.go @@ -148,11 +148,9 @@ func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) { s.renderError(w, http.StatusInternalServerError, errServerError, "") return } - state := authReq.ID - if len(s.connectors) == 1 { for id := range s.connectors { - http.Redirect(w, r, s.absPath("/auth", id)+"?state="+state, http.StatusFound) + http.Redirect(w, r, s.absPath("/auth", id)+"?req="+authReq.ID, http.StatusFound) return } } @@ -168,7 +166,7 @@ func (s *Server) handleAuthorization(w http.ResponseWriter, r *http.Request) { i++ } - s.templates.login(w, connectorInfos, state) + s.templates.login(w, connectorInfos, authReq.ID) } func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) { @@ -179,7 +177,7 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) { return } - authReqID := r.FormValue("state") + authReqID := r.FormValue("req") // TODO(ericchiang): cache user identity. @@ -198,6 +196,9 @@ func (s *Server) handleConnectorLogin(w http.ResponseWriter, r *http.Request) { switch conn := conn.Connector.(type) { case connector.CallbackConnector: + // Use the auth request ID as the "state" token. + // + // TODO(ericchiang): Is this appropriate or should we also be using a nonce? callbackURL, err := conn.LoginURL(s.absURL("/callback"), authReqID) if err != nil { log.Printf("Connector %q returned error when creating callback: %v", connID, err) @@ -342,11 +343,11 @@ func (s *Server) finalizeLogin(identity connector.Identity, authReq storage.Auth if err := s.storage.UpdateAuthRequest(authReq.ID, updater); err != nil { return "", fmt.Errorf("failed to update auth request: %v", err) } - return path.Join(s.issuerURL.Path, "/approval") + "?state=" + authReq.ID, nil + return path.Join(s.issuerURL.Path, "/approval") + "?req=" + authReq.ID, nil } func (s *Server) handleApproval(w http.ResponseWriter, r *http.Request) { - authReq, err := s.storage.GetAuthRequest(r.FormValue("state")) + authReq, err := s.storage.GetAuthRequest(r.FormValue("req")) if err != nil { log.Printf("Failed to get auth request: %v", err) s.renderError(w, http.StatusInternalServerError, errServerError, "") diff --git a/server/templates.go b/server/templates.go index 117d12c55e315073b48a25b2f85c11993709b1e5..e8285fe31e26b579b076cc430289ec8fe1f2b10b 100644 --- a/server/templates.go +++ b/server/templates.go @@ -138,29 +138,29 @@ func (n byName) Len() int { return len(n) } func (n byName) Less(i, j int) bool { return n[i].Name < n[j].Name } func (n byName) Swap(i, j int) { n[i], n[j] = n[j], n[i] } -func (t *templates) login(w http.ResponseWriter, connectors []connectorInfo, state string) { +func (t *templates) login(w http.ResponseWriter, connectors []connectorInfo, authReqID string) { sort.Sort(byName(connectors)) data := struct { TemplateConfig Connectors []connectorInfo - State string - }{t.globalData, connectors, state} + AuthReqID string + }{t.globalData, connectors, authReqID} renderTemplate(w, t.loginTmpl, data) } -func (t *templates) password(w http.ResponseWriter, state, callback, lastUsername string, lastWasInvalid bool) { +func (t *templates) password(w http.ResponseWriter, authReqID, callback, lastUsername string, lastWasInvalid bool) { data := struct { TemplateConfig - State string - PostURL string - Username string - Invalid bool - }{t.globalData, state, callback, lastUsername, lastWasInvalid} + AuthReqID string + PostURL string + Username string + Invalid bool + }{t.globalData, authReqID, callback, lastUsername, lastWasInvalid} renderTemplate(w, t.passwordTmpl, data) } -func (t *templates) approval(w http.ResponseWriter, state, username, clientName string, scopes []string) { +func (t *templates) approval(w http.ResponseWriter, authReqID, username, clientName string, scopes []string) { accesses := []string{} for _, scope := range scopes { access, ok := scopeDescriptions[scope] @@ -171,11 +171,11 @@ func (t *templates) approval(w http.ResponseWriter, state, username, clientName sort.Strings(accesses) data := struct { TemplateConfig - User string - Client string - State string - Scopes []string - }{t.globalData, username, clientName, state, accesses} + User string + Client string + AuthReqID string + Scopes []string + }{t.globalData, username, clientName, authReqID, accesses} renderTemplate(w, t.approvalTmpl, data) } diff --git a/server/templates_default.go b/server/templates_default.go index 3a3d031a2bdec7ab779d66527ece476ba18a3791..651c7411b8c9eaa9a7f26fae82aa59533ad31427 100644 --- a/server/templates_default.go +++ b/server/templates_default.go @@ -25,7 +25,7 @@ var defaultTemplates = map[string]string{ <div> <div class="form-row"> <form method="post"> - <input type="hidden" name="state" value="{{ .State }}"/> + <input type="hidden" name="req" value="{{ .AuthReqID }}"/> <input type="hidden" name="approval" value="approve"> <button type="submit" class="btn btn-success"> <span class="btn-text">Grant Access</span> @@ -34,7 +34,7 @@ var defaultTemplates = map[string]string{ </div> <div class="form-row"> <form method="post"> - <input type="hidden" name="state" value="{{ .State }}"/> + <input type="hidden" name="req" value="{{ .AuthReqID }}"/> <input type="hidden" name="approval" value="rejected"> <button type="submit" class="btn btn-provider"> <span class="btn-text">Cancel</span> @@ -300,7 +300,7 @@ var defaultTemplates = map[string]string{ <div> {{ range $c := .Connectors }} <div class="form-row"> - <a href="{{ $c.URL }}?state={{ $.State }}" target="_self"> + <a href="{{ $c.URL }}?req={{ $.AuthReqID }}" target="_self"> <button class="btn btn-provider"> <span class="btn-icon btn-icon-{{ $c.ID }}"></span> <span class="btn-text">Log in with {{ $c.Name }}</span> @@ -344,7 +344,7 @@ var defaultTemplates = map[string]string{ </div> <input tabindex="2" required id="password" name="password" type="password" class="input-box" placeholder="password" {{ if .Invalid }} autofocus {{ end }}/> </div> - <input type="hidden" name="state" value="{{ .State }}"/> + <input type="hidden" name="req" value="{{ .AuthReqID }}"/> {{ if .Invalid }} <div class="error-box"> diff --git a/web/templates/approval.html b/web/templates/approval.html index c73a522e0d6cfde30e9a4aa7fbde26e7065cf122..076049c0b2a57d94d8961ee813f8a21c76788d61 100644 --- a/web/templates/approval.html +++ b/web/templates/approval.html @@ -19,7 +19,7 @@ <div> <div class="form-row"> <form method="post"> - <input type="hidden" name="state" value="{{ .State }}"/> + <input type="hidden" name="req" value="{{ .AuthReqID }}"/> <input type="hidden" name="approval" value="approve"> <button type="submit" class="btn btn-success"> <span class="btn-text">Grant Access</span> @@ -28,7 +28,7 @@ </div> <div class="form-row"> <form method="post"> - <input type="hidden" name="state" value="{{ .State }}"/> + <input type="hidden" name="req" value="{{ .AuthReqID }}"/> <input type="hidden" name="approval" value="rejected"> <button type="submit" class="btn btn-provider"> <span class="btn-text">Cancel</span> diff --git a/web/templates/login.html b/web/templates/login.html index d43b5142773425057774ead2a8b09ecdbbc1ddff..ea43903a538e55b652babf21dc4f0ec722b6dd58 100644 --- a/web/templates/login.html +++ b/web/templates/login.html @@ -6,7 +6,7 @@ <div> {{ range $c := .Connectors }} <div class="form-row"> - <a href="{{ $c.URL }}?state={{ $.State }}" target="_self"> + <a href="{{ $c.URL }}?req={{ $.AuthReqID }}" target="_self"> <button class="btn btn-provider"> <span class="btn-icon btn-icon-{{ $c.ID }}"></span> <span class="btn-text">Log in with {{ $c.Name }}</span> diff --git a/web/templates/password.html b/web/templates/password.html index 89f833fcdcd2f5a840ab8584877061669324aeb8..7a9ffb14ca9e1e0d332a2eba1d1eda1213c627f3 100644 --- a/web/templates/password.html +++ b/web/templates/password.html @@ -15,7 +15,7 @@ </div> <input tabindex="2" required id="password" name="password" type="password" class="input-box" placeholder="password" {{ if .Invalid }} autofocus {{ end }}/> </div> - <input type="hidden" name="state" value="{{ .State }}"/> + <input type="hidden" name="req" value="{{ .AuthReqID }}"/> {{ if .Invalid }} <div class="error-box">