Skip to content

Commit a5fff88

Browse files
committed
Re-enstate the use of PSR-7 requests
1 parent 93b4c73 commit a5fff88

File tree

2 files changed

+32
-132
lines changed

2 files changed

+32
-132
lines changed

src/SAML2/HTTPRedirect.php

Lines changed: 14 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)