@@ -14,7 +14,7 @@ def self.inherited(subclass)
1414 RUBYSAML_RESPONSE_OPTIONS = OneLogin ::RubySaml ::Response ::AVAILABLE_OPTIONS
1515
1616 option :name_identifier_format , nil
17- option :idp_sso_service_url_runtime_params , { }
17+ option :idp_sso_service_url_runtime_params , { RelayState : 'RelayState' }
1818 option :request_attributes , [
1919 { :name => 'email' , :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic' , :friendly_name => 'Email address' } ,
2020 { :name => 'name' , :name_format => 'urn:oasis:names:tc:SAML:2.0:attrname-format:basic' , :friendly_name => 'Full name' } ,
@@ -139,6 +139,22 @@ def find_attribute_by(keys)
139139 nil
140140 end
141141
142+ def mock_request_call
143+ # Per SAML 2.0, if a RelayState param is passed, IDPs "MUST place the exact RelayState
144+ # data it received with the request into the corresponding RelayState parameter in the response."
145+ #
146+ # By default, the "mock" `OmniAuth::Strategy` implementation will forward along any URL params,
147+ # so we can in turn take any POSTed RelayState params and put them in the GET query string:
148+ query_hash = request . GET . merge! ( additional_params_for_authn_request . slice ( 'RelayState' ) )
149+ query_string = Rack ::Utils . build_query ( query_hash )
150+
151+ request . set_header ( Rack ::QUERY_STRING , query_string )
152+ request . set_header ( Rack ::RACK_REQUEST_QUERY_STRING , query_string )
153+ request . set_header ( Rack ::RACK_REQUEST_QUERY_HASH , query_hash )
154+
155+ super
156+ end
157+
142158 private
143159
144160 def request_path_pattern
0 commit comments