@@ -120,41 +120,26 @@ public function send(AbstractMessage $message): ResponseInterface
120120 */
121121 public function receive (ServerRequestInterface $ request ): AbstractMessage
122122 {
123- $ query = $ this ->parseQuery ();
124- $ signedQuery = $ query ['SignedQuery ' ];
125-
126- /**
127- * Get the SAMLRequest/SAMLResponse from the exact same signed data that will be verified later in
128- * validateSignature into $res using the actual SignedQuery
129- */
130- $ res = [];
131- foreach (explode ('& ' , $ signedQuery ) as $ e ) {
132- $ tmp = explode ('= ' , $ e , 2 );
133- $ name = $ tmp [0 ];
134- if (count ($ tmp ) === 2 ) {
135- $ value = $ tmp [1 ];
136- } else {
137- /* No value for this parameter. */
138- $ value = '' ;
139- }
140- $ name = urldecode ($ name );
141- $ res [$ name ] = urldecode ($ value );
142- }
123+ $ query = $ request ->getQueryParams ();
143124
144125 /**
145126 * Put the SAMLRequest/SAMLResponse from the actual query string into $message,
146127 * and assert that the result from parseQuery() in $query and the parsing of the SignedQuery in $res agree
147128 */
148- if (array_key_exists ('SAMLRequest ' , $ res )) {
149- Assert:: same ( $ res [ ' SAMLRequest ' ], $ query ['SAMLRequest ' ], ' Parse failure. ' );
150- $ message = $ res ['SAMLRequest ' ];
151- } elseif (array_key_exists ('SAMLResponse ' , $ res )) {
152- Assert:: same ( $ res [ ' SAMLResponse ' ], $ query ['SAMLResponse ' ], ' Parse failure. ' );
153- $ message = $ res ['SAMLResponse ' ];
129+ if (array_key_exists ('SAMLRequest ' , $ query )) {
130+ $ message = urldecode ( $ query ['SAMLRequest ' ]);
131+ $ signedQuery = ' SAMLRequest= ' . urlencode ( $ query ['SAMLRequest ' ]) ;
132+ } elseif (array_key_exists ('SAMLResponse ' , $ query )) {
133+ $ message = urldecode ( $ query ['SAMLResponse ' ]);
134+ $ signedQuery = ' SAMLResponse= ' . urlencode ( $ query ['SAMLResponse ' ]) ;
154135 } else {
155136 throw new Exception ('Missing SAMLRequest or SAMLResponse parameter. ' );
156137 }
157138
139+ if (array_key_exists ('SAMLRequest ' , $ query ) && array_key_exists ('SAMLResponse ' , $ query )) {
140+ throw new Exception ('Both SAMLRequest and SAMLResponse provided. ' );
141+ }
142+
158143 if (isset ($ query ['SAMLEncoding ' ]) && $ query ['SAMLEncoding ' ] !== C::BINDING_HTTP_REDIRECT_DEFLATE ) {
159144 throw new Exception (sprintf ('Unknown SAMLEncoding: %s ' , $ query ['SAMLEncoding ' ]));
160145 }
@@ -175,6 +160,7 @@ public function receive(ServerRequestInterface $request): AbstractMessage
175160
176161 if (array_key_exists ('RelayState ' , $ query )) {
177162 $ this ->setRelayState ($ query ['RelayState ' ]);
163+ $ signedQuery = 'SAMLRequest= ' . urlencode ($ query ['SAMLRequest ' ]);
178164 }
179165
180166 if (!array_key_exists ('Signature ' , $ query )) {
@@ -192,6 +178,8 @@ public function receive(ServerRequestInterface $request): AbstractMessage
192178
193179 if (!array_key_exists ('SigAlg ' , $ query )) {
194180 throw new Exception ('Missing signature algorithm. ' );
181+ } else {
182+ $ signedQuery .= '&SigAlg= ' . urlencode ($ query ['SigAlg ' ]);
195183 }
196184
197185 $ container = ContainerSingleton::getInstance ();
@@ -208,67 +196,4 @@ public function receive(ServerRequestInterface $request): AbstractMessage
208196
209197 return $ message ;
210198 }
211-
212-
213- /**
214- * Helper function to parse query data.
215- *
216- * This function returns the query string split into key=>value pairs.
217- * It also adds a new parameter, SignedQuery, which contains the data that is
218- * signed.
219- *
220- * @return array The query data that is signed.
221- * @throws \Exception
222- */
223- private static function parseQuery (): array
224- {
225- /*
226- * Parse the query string. We need to do this ourself, so that we get access
227- * to the raw (urlencoded) values. This is required because different software
228- * can urlencode to different values.
229- */
230- $ data = [];
231- $ relayState = '' ;
232- $ sigAlg = '' ;
233- $ sigQuery = '' ;
234-
235- foreach (explode ('& ' , $ _SERVER ['QUERY_STRING ' ]) as $ e ) {
236- $ tmp = explode ('= ' , $ e , 2 );
237- $ name = $ tmp [0 ];
238- if (count ($ tmp ) === 2 ) {
239- $ value = $ tmp [1 ];
240- } else {
241- /* No value for this parameter. */
242- $ value = '' ;
243- }
244-
245- $ name = urldecode ($ name );
246- // Prevent keys from being set more than once
247- if (array_key_exists ($ name , $ data )) {
248- throw new Exception ('Duplicate parameter. ' );
249- }
250- $ data [$ name ] = urldecode ($ value );
251-
252- switch ($ name ) {
253- case 'SAMLRequest ' :
254- case 'SAMLResponse ' :
255- $ sigQuery = $ name . '= ' . $ value ;
256- break ;
257- case 'RelayState ' :
258- $ relayState = '&RelayState= ' . $ value ;
259- break ;
260- case 'SigAlg ' :
261- $ sigAlg = '&SigAlg= ' . $ value ;
262- break ;
263- }
264- }
265-
266- if (array_key_exists ('SAMLRequest ' , $ data ) && array_key_exists ('SAMLResponse ' , $ data )) {
267- throw new Exception ('Both SAMLRequest and SAMLResponse provided. ' );
268- }
269-
270- $ data ['SignedQuery ' ] = $ sigQuery . $ relayState . $ sigAlg ;
271-
272- return $ data ;
273- }
274199}
0 commit comments