@@ -123,41 +123,26 @@ public function send(AbstractMessage $message): ResponseInterface
123123 */
124124 public function receive (ServerRequestInterface $ request ): AbstractMessage
125125 {
126- $ query = $ this ->parseQuery ();
127- $ signedQuery = $ query ['SignedQuery ' ];
128-
129- /**
130- * Get the SAMLRequest/SAMLResponse from the exact same signed data that will be verified later in
131- * validateSignature into $res using the actual SignedQuery
132- */
133- $ res = [];
134- foreach (explode ('& ' , $ signedQuery ) as $ e ) {
135- $ tmp = explode ('= ' , $ e , 2 );
136- $ name = $ tmp [0 ];
137- if (count ($ tmp ) === 2 ) {
138- $ value = $ tmp [1 ];
139- } else {
140- /* No value for this parameter. */
141- $ value = '' ;
142- }
143- $ name = urldecode ($ name );
144- $ res [$ name ] = urldecode ($ value );
145- }
126+ $ query = $ request ->getQueryParams ();
146127
147128 /**
148129 * Put the SAMLRequest/SAMLResponse from the actual query string into $message,
149130 * and assert that the result from parseQuery() in $query and the parsing of the SignedQuery in $res agree
150131 */
151- if (array_key_exists ('SAMLRequest ' , $ res )) {
152- Assert:: same ( $ res [ ' SAMLRequest ' ], $ query ['SAMLRequest ' ], ' Parse failure. ' ) ;
153- $ message = $ res ['SAMLRequest ' ];
154- } elseif (array_key_exists ('SAMLResponse ' , $ res )) {
155- Assert:: same ( $ res [ ' SAMLResponse ' ], $ query ['SAMLResponse ' ], ' Parse failure. ' ) ;
156- $ message = $ res ['SAMLResponse ' ];
132+ if (array_key_exists ('SAMLRequest ' , $ query )) {
133+ $ message = $ query ['SAMLRequest ' ];
134+ $ signedQuery = ' SAMLRequest= ' . urlencode ( $ query ['SAMLRequest ' ]) ;
135+ } elseif (array_key_exists ('SAMLResponse ' , $ query )) {
136+ $ message = $ query ['SAMLResponse ' ];
137+ $ signedQuery = ' SAMLResponse= ' . urlencode ( $ query ['SAMLResponse ' ]) ;
157138 } else {
158139 throw new Exception ('Missing SAMLRequest or SAMLResponse parameter. ' );
159140 }
160141
142+ if (array_key_exists ('SAMLRequest ' , $ query ) && array_key_exists ('SAMLResponse ' , $ query )) {
143+ throw new Exception ('Both SAMLRequest and SAMLResponse provided. ' );
144+ }
145+
161146 if (isset ($ query ['SAMLEncoding ' ]) && $ query ['SAMLEncoding ' ] !== C::BINDING_HTTP_REDIRECT_DEFLATE ) {
162147 throw new Exception (sprintf ('Unknown SAMLEncoding: %s ' , $ query ['SAMLEncoding ' ]));
163148 }
@@ -178,6 +163,7 @@ public function receive(ServerRequestInterface $request): AbstractMessage
178163
179164 if (array_key_exists ('RelayState ' , $ query )) {
180165 $ this ->setRelayState ($ query ['RelayState ' ]);
166+ $ signedQuery .= '&RelayState= ' . urlencode ($ query ['RelayState ' ]);
181167 }
182168
183169 if (!array_key_exists ('Signature ' , $ query )) {
@@ -196,6 +182,8 @@ public function receive(ServerRequestInterface $request): AbstractMessage
196182
197183 if (!array_key_exists ('SigAlg ' , $ query )) {
198184 throw new Exception ('Missing signature algorithm. ' );
185+ } else {
186+ $ signedQuery .= '&SigAlg= ' . urlencode ($ query ['SigAlg ' ]);
199187 }
200188
201189 $ container = ContainerSingleton::getInstance ();
@@ -212,67 +200,4 @@ public function receive(ServerRequestInterface $request): AbstractMessage
212200
213201 return $ message ;
214202 }
215-
216-
217- /**
218- * Helper function to parse query data.
219- *
220- * This function returns the query string split into key=>value pairs.
221- * It also adds a new parameter, SignedQuery, which contains the data that is
222- * signed.
223- *
224- * @return array The query data that is signed.
225- * @throws \Exception
226- */
227- private static function parseQuery (): array
228- {
229- /*
230- * Parse the query string. We need to do this ourself, so that we get access
231- * to the raw (urlencoded) values. This is required because different software
232- * can urlencode to different values.
233- */
234- $ data = [];
235- $ relayState = '' ;
236- $ sigAlg = '' ;
237- $ sigQuery = '' ;
238-
239- foreach (explode ('& ' , $ _SERVER ['QUERY_STRING ' ]) as $ e ) {
240- $ tmp = explode ('= ' , $ e , 2 );
241- $ name = $ tmp [0 ];
242- if (count ($ tmp ) === 2 ) {
243- $ value = $ tmp [1 ];
244- } else {
245- /* No value for this parameter. */
246- $ value = '' ;
247- }
248-
249- $ name = urldecode ($ name );
250- // Prevent keys from being set more than once
251- if (array_key_exists ($ name , $ data )) {
252- throw new Exception ('Duplicate parameter. ' );
253- }
254- $ data [$ name ] = urldecode ($ value );
255-
256- switch ($ name ) {
257- case 'SAMLRequest ' :
258- case 'SAMLResponse ' :
259- $ sigQuery = $ name . '= ' . $ value ;
260- break ;
261- case 'RelayState ' :
262- $ relayState = '&RelayState= ' . $ value ;
263- break ;
264- case 'SigAlg ' :
265- $ sigAlg = '&SigAlg= ' . $ value ;
266- break ;
267- }
268- }
269-
270- if (array_key_exists ('SAMLRequest ' , $ data ) && array_key_exists ('SAMLResponse ' , $ data )) {
271- throw new Exception ('Both SAMLRequest and SAMLResponse provided. ' );
272- }
273-
274- $ data ['SignedQuery ' ] = $ sigQuery . $ relayState . $ sigAlg ;
275-
276- return $ data ;
277- }
278203}
0 commit comments