diff --git a/lib/saml2.coffee b/lib/saml2.coffee index 09ac50e..a0d0f36 100644 --- a/lib/saml2.coffee +++ b/lib/saml2.coffee @@ -568,12 +568,16 @@ module.exports.ServiceProvider = xml = create_logout_request @entity_id, options.name_id, options.session_index, identity_provider.sso_logout_url zlib.deflateRaw xml, (err, deflated) => return cb err if err? - uri = url.parse identity_provider.sso_logout_url + uri = url.parse identity_provider.sso_logout_url, true + query = null if options.sign_get_request - uri.query = sign_request deflated.toString('base64'), @private_key, options.relay_state + query = sign_request deflated.toString('base64'), @private_key, options.relay_state else - uri.query = SAMLRequest: deflated.toString 'base64' - uri.query.RelayState = options.relay_state if options.relay_state? + query = SAMLRequest: deflated.toString 'base64' + query.RelayState = options.relay_state if options.relay_state? + uri.query = _.extend(query, uri.query) + uri.search = null + uri.query = query cb null, url.format(uri) # Returns: diff --git a/test/saml2.coffee b/test/saml2.coffee index 3377a70..c7a62ea 100644 --- a/test/saml2.coffee +++ b/test/saml2.coffee @@ -624,6 +624,35 @@ describe 'saml2', -> assert parsed_url?.query?.Signature?, 'LogoutRequest is not signed' done() + it 'can create logout request url using an idp with query string parameter', (done) -> + sp_options = + entity_id: 'https://sp.example.com/metadata.xml' + private_key: get_test_file('test.pem') + certificate: get_test_file('test.crt') + assert_endpoint: 'https://sp.example.com/assert' + idp_options = + sso_login_url: 'https://idp.example.com/login' + sso_logout_url: 'https://idp.example.com?action=logout' + certificates: get_test_file('test.crt') + request_options = + name_id: 'name_id' + session_index: 'session_index' + sign_get_request: true + + sp = new saml2.ServiceProvider sp_options + idp = new saml2.IdentityProvider idp_options + + async.waterfall [ + (cb_wf) -> sp.create_logout_request_url idp, request_options, cb_wf + ], (err, logout_url) -> + assert not err?, "Error creating logout URL: #{err}" + parsed_url = url.parse logout_url, true + console.log parsed_url + assert parsed_url?.query?.SAMLRequest?, 'Could not find SAMLRequest in url query parameters' + assert parsed_url?.query?.Signature?, 'LogoutRequest is not signed' + assert parsed_url?.query?.action?, 'Could not find action in url query parameters' + done() + it 'can create logout request url using an string sso_logout_url', (done) -> sp_options = entity_id: 'https://sp.example.com/metadata.xml'