From 0cb184316a6ef5cd39d7053c6a5388416ee6ec06 Mon Sep 17 00:00:00 2001 From: Jacob Klapwijk Date: Tue, 8 Dec 2020 10:54:28 +0100 Subject: [PATCH] Use Singlelogout response url in LogoutResponse if set Co-authored-by: Sofia Canclini --- lib/onelogin/ruby-saml/slo_logoutresponse.rb | 9 ++++++--- test/slo_logoutresponse_test.rb | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/onelogin/ruby-saml/slo_logoutresponse.rb b/lib/onelogin/ruby-saml/slo_logoutresponse.rb index beecb1016..827e1d0b4 100644 --- a/lib/onelogin/ruby-saml/slo_logoutresponse.rb +++ b/lib/onelogin/ruby-saml/slo_logoutresponse.rb @@ -32,14 +32,15 @@ def initialize def create(settings, request_id = nil, logout_message = nil, params = {}) params = create_params(settings, request_id, logout_message, params) params_prefix = (settings.idp_slo_target_url =~ /\?/) ? '&' : '?' + url = settings.idp_slo_response_service_url || settings.idp_slo_target_url saml_response = CGI.escape(params.delete("SAMLResponse")) response_params = "#{params_prefix}SAMLResponse=#{saml_response}" params.each_pair do |key, value| response_params << "&#{key.to_s}=#{CGI.escape(value.to_s)}" end - raise SettingError.new "Invalid settings, idp_slo_target_url is not set!" if settings.idp_slo_target_url.nil? or settings.idp_slo_target_url.empty? - @logout_url = settings.idp_slo_target_url + response_params + raise SettingError.new "Invalid settings, idp_slo_target_url is not set!" if url.nil? or url.empty? + @logout_url = url + response_params end # Creates the Get parameters for the logout response. @@ -109,12 +110,14 @@ def create_xml_document(settings, request_id = nil, logout_message = nil) response_doc = XMLSecurity::Document.new response_doc.uuid = uuid + destination = settings.idp_slo_response_service_url || settings.idp_slo_target_url + root = response_doc.add_element 'samlp:LogoutResponse', { 'xmlns:samlp' => 'urn:oasis:names:tc:SAML:2.0:protocol', "xmlns:saml" => "urn:oasis:names:tc:SAML:2.0:assertion" } root.attributes['ID'] = uuid root.attributes['IssueInstant'] = time root.attributes['Version'] = '2.0' root.attributes['InResponseTo'] = request_id unless request_id.nil? - root.attributes['Destination'] = settings.idp_slo_target_url unless settings.idp_slo_target_url.nil? or settings.idp_slo_target_url.empty? + root.attributes['Destination'] = destination unless destination.nil? or destination.empty? if settings.sp_entity_id != nil issuer = root.add_element "saml:Issuer" diff --git a/test/slo_logoutresponse_test.rb b/test/slo_logoutresponse_test.rb index 189037cf6..176fce951 100644 --- a/test/slo_logoutresponse_test.rb +++ b/test/slo_logoutresponse_test.rb @@ -65,6 +65,16 @@ class SloLogoutresponseTest < Minitest::Test assert_match /Custom Logout Message<\/samlp:StatusMessage>/, inflated end + it "uses the response location when set" do + settings.idp_slo_response_service_url = "http://unauth.com/logout/return" + + unauth_url = OneLogin::RubySaml::SloLogoutresponse.new.create(settings, logout_request.id) + assert_match /^http:\/\/unauth\.com\/logout\/return\?SAMLResponse=/, unauth_url + + inflated = decode_saml_response_payload(unauth_url) + assert_match /Destination='http:\/\/unauth.com\/logout\/return'/, inflated + end + describe "when the settings indicate to sign (embedded) logout response" do before do