-
Notifications
You must be signed in to change notification settings - Fork 440
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
bug: make logout request need add signature logic if sp.SignatureMethod
is not empty.
#550
Comments
Im currently having issues with a logout request with a national IdP but it seems to be that the idp does not understand the signature generated. I believe the logout request is signed in Line 1161 in a32b643
called from Line 1216 in a32b643
|
I think you can ref this link for how to make a SAML logout request: https://stackoverflow.com/a/8215470 |
Your are right @ronething, the signature and algorithm needs to be included in the request, but i I think they are?! Here i copied an example of my logout request.
I did modify the request slightly as I added the session Index paramter and changed the NameId to be the Principal and not the SP (I believe that these are required by the saml standard but should be reported as seperat bugs). anyway the custom codesnippet i have is here:
I can recommend using the chrome extension for http://rcfed.com/ to record your saml request for debugging |
@gravgaard maybe you can try this patch on the this repo, or implement diff --git a/service_provider.go b/service_provider.go
index 30b3567..6a2b6b6 100644
--- a/service_provider.go
+++ b/service_provider.go
@@ -1229,11 +1229,12 @@ func (sp *ServiceProvider) MakeRedirectLogoutRequest(nameID, relayState string)
if err != nil {
return nil, err
}
- return req.Redirect(relayState), nil
+
+ return req.Redirect(relayState, sp)
}
// Redirect returns a URL suitable for using the redirect binding with the request
-func (r *LogoutRequest) Redirect(relayState string) *url.URL {
+func (r *LogoutRequest) Redirect(relayState string, sp *ServiceProvider) (*url.URL, error) {
w := &bytes.Buffer{}
w1 := base64.NewEncoder(base64.StdEncoding, w)
w2, _ := flate.NewWriter(w1, 9)
@@ -1251,14 +1252,35 @@ func (r *LogoutRequest) Redirect(relayState string) *url.URL {
rv, _ := url.Parse(r.Destination)
- query := rv.Query()
- query.Set("SAMLRequest", w.String())
+ query := rv.RawQuery
+ if len(query) > 0 {
+ query += "&SAMLRequest=" + url.QueryEscape(w.String())
+ } else {
+ query += "SAMLRequest=" + url.QueryEscape(w.String())
+ }
+
if relayState != "" {
- query.Set("RelayState", relayState)
+ query += "&RelayState=" + relayState
}
- rv.RawQuery = query.Encode()
- return rv
+ if len(sp.SignatureMethod) > 0 {
+ query += "&SigAlg=" + url.QueryEscape(sp.SignatureMethod)
+ signingContext, err := GetSigningContext(sp)
+
+ if err != nil {
+ return nil, err
+ }
+
+ sig, err := signingContext.SignString(query)
+ if err != nil {
+ return nil, err
+ }
+ query += "&Signature=" + url.QueryEscape(base64.StdEncoding.EncodeToString(sig))
+ }
+
+ rv.RawQuery = query
+
+ return rv, nil
}
// MakePostLogoutRequest creates a SAML authentication request using |
@ronething holy moly you are right. It totally worked 🍻. So you are right:
As matter of fact your suggestion is the exact same way the authn request are made: Line 405 in a32b643
|
Yeah, as mentioned in this issue's description. |
Note that when using https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf
Since the request data is constructed with
There needs to be additional handling for removing the signature before constructing the |
no signature when make logout request. If IDP enables Client signature required, it will cause signature verification to fail.
saml/service_provider.go
Lines 1235 to 1262 in a32b643
ref: make authn request.
saml/service_provider.go
Lines 248 to 295 in a32b643
The text was updated successfully, but these errors were encountered: