Skip to content

Commit

Permalink
construct AuthnRequest signature with proper query ordering
Browse files Browse the repository at this point in the history
  • Loading branch information
beyang committed Aug 20, 2018
1 parent 4f38118 commit 1b90112
Showing 1 changed file with 23 additions and 1 deletion.
24 changes: 23 additions & 1 deletion build_request.go
Expand Up @@ -153,7 +153,7 @@ func (sp *SAMLServiceProvider) buildAuthURLFromDocument(relayState, binding stri
ctx := sp.SigningContext()
qs.Add("SigAlg", ctx.GetSignatureMethodIdentifier())
var rawSignature []byte
if rawSignature, err = ctx.SignString(qs.Encode()); err != nil {
if rawSignature, err = ctx.SignString(signatureInputString(qs.Get("SAMLRequest"), qs.Get("RelayState"), qs.Get("SigAlg"))); err != nil {
return "", fmt.Errorf("unable to sign query string of redirect URL: %v", err)
}

Expand Down Expand Up @@ -194,3 +194,25 @@ func (sp *SAMLServiceProvider) AuthRedirect(w http.ResponseWriter, r *http.Reque
http.Redirect(w, r, url, http.StatusFound)
return nil
}

// signatureInputString constructs the string to be fed into the signature algorithm, as described
// in section 3.4.4.1 of
// https://www.oasis-open.org/committees/download.php/56779/sstc-saml-bindings-errata-2.0-wd-06.pdf
func signatureInputString(samlRequest, relayState, sigAlg string) string {
var params [][2]string
if relayState == "" {
params = [][2]string{{"SAMLRequest", samlRequest}, {"SigAlg", sigAlg}}
} else {
params = [][2]string{{"SAMLRequest", samlRequest}, {"RelayState", relayState}, {"SigAlg", sigAlg}}
}

var buf bytes.Buffer
for _, kv := range params {
k, v := kv[0], kv[1]
if buf.Len() > 0 {
buf.WriteByte('&')
}
buf.WriteString(url.QueryEscape(k) + "=" + url.QueryEscape(v))
}
return buf.String()
}

0 comments on commit 1b90112

Please sign in to comment.