1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* abstract strategy for checking auth against parts of the request |
4
|
|
|
*/ |
5
|
|
|
|
6
|
|
|
namespace Graviton\SecurityBundle\Authentication\Strategies; |
7
|
|
|
|
8
|
|
|
use Symfony\Component\HttpFoundation\HeaderBag; |
9
|
|
|
use Symfony\Component\HttpFoundation\ParameterBag; |
10
|
|
|
use Symfony\Component\HttpFoundation\Response; |
11
|
|
|
use Symfony\Component\HttpKernel\Exception\HttpException; |
12
|
|
|
use Symfony\Component\DependencyInjection\Container; |
13
|
|
|
use Symfony\Component\HttpFoundation\RequestStack; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* Class AbstractHttpStrategy |
17
|
|
|
* |
18
|
|
|
* @author List of contributors <https://github.com/libgraviton/graviton/graphs/contributors> |
19
|
|
|
* @license http://opensource.org/licenses/gpl-license.php GNU Public License |
20
|
|
|
* @link http://swisscom.ch |
21
|
|
|
*/ |
22
|
|
|
abstract class AbstractHttpStrategy implements StrategyInterface |
23
|
|
|
{ |
24
|
|
|
/** @var Container */ |
25
|
|
|
protected $container; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* Extracts information from the a request header field. |
29
|
|
|
* |
30
|
|
|
* @param ParameterBag|HeaderBag $header object representation of the request header. |
31
|
|
|
* @param string $fieldname Name of the field to be read. |
32
|
|
|
* |
33
|
|
|
* @return string |
34
|
|
|
*/ |
35
|
|
|
protected function extractFieldInfo($header, $fieldname) |
36
|
|
|
{ |
37
|
|
|
if ($header instanceof ParameterBag || $header instanceof HeaderBag) { |
38
|
|
|
$this->validateField($header, $fieldname); |
39
|
|
|
$bagValue = $header->get($fieldname, ''); |
40
|
|
|
} else { |
41
|
|
|
throw new \InvalidArgumentException('Provided request information are not valid.'); |
42
|
|
|
} |
43
|
|
|
|
44
|
|
|
// Cookie value can be a coma separated string |
45
|
|
|
$extractField = $this->container->getParameter('graviton.security.core_extract_username'); |
46
|
|
|
|
47
|
|
|
// Get Original requested Value. |
48
|
|
|
if (!$extractField) { |
49
|
|
|
return $bagValue; |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
$pattern = "/((?m)(?<=\b{$extractField}=)[^,]*)/i"; |
53
|
|
|
preg_match($pattern,$bagValue, $matches); |
54
|
|
|
if ( !$matches ) { |
|
|
|
|
55
|
|
|
return ''; |
56
|
|
|
} |
57
|
|
|
$fieldValue = $matches[0]; |
58
|
|
|
|
59
|
|
|
if (($clientIdName = $this->container->getParameter('graviton.security.core_id_name')) |
60
|
|
|
&& ($extractId = $this->container->getParameter('graviton.security.core_extract_core_id'))) |
61
|
|
|
{ |
62
|
|
|
$pattern = "/((?m)(?<=\b{$extractId}=)[^,]*)/i"; |
63
|
|
|
preg_match($pattern, $bagValue, $matches); |
64
|
|
|
if ( $matches ) { |
|
|
|
|
65
|
|
|
/** @var RequestStack $requestStack */ |
66
|
|
|
$requestStack = $this->container->get('request_stack'); |
67
|
|
|
$requestStack->getCurrentRequest()->attributes->set($clientIdName, $matches[0]); |
68
|
|
|
} |
69
|
|
|
} |
70
|
|
|
|
71
|
|
|
return $fieldValue; |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* Verifies that the provided header has the expected/mandatory fields. |
76
|
|
|
* |
77
|
|
|
* @param ParameterBag|HeaderBag $header object representation of the request header. |
78
|
|
|
* @param string $fieldName Name of the header field to be validated. |
79
|
|
|
* |
80
|
|
|
* @return void |
81
|
|
|
* @throws \Symfony\Component\HttpKernel\Exception\HttpException |
82
|
|
|
*/ |
83
|
|
|
protected function validateField($header, $fieldName) |
84
|
|
|
{ |
85
|
|
|
$passed = $header->has($fieldName); |
86
|
|
|
|
87
|
|
|
// return without exception so we can return a dummy user |
88
|
|
|
if (true === $passed) { |
89
|
|
|
// get rid of anything not a valid character |
90
|
|
|
$authInfo = filter_var($header->get($fieldName), FILTER_SANITIZE_STRING); |
91
|
|
|
|
92
|
|
|
// get rid of whitespaces |
93
|
|
|
$patterns = array("\r\n", "\n", "\r", "\s", "\t"); |
94
|
|
|
$authInfo = str_replace($patterns, "", trim($authInfo)); |
95
|
|
|
|
96
|
|
|
// get rid of control characters |
97
|
|
|
if (empty($authInfo) || $authInfo !== preg_replace('#[[:cntrl:]]#i', '', $authInfo)) { |
98
|
|
|
throw new HttpException( |
99
|
|
|
Response::HTTP_NETWORK_AUTHENTICATION_REQUIRED, |
100
|
|
|
'Mandatory header field (' . $fieldName . ') not provided or invalid.' |
101
|
|
|
); |
102
|
|
|
} |
103
|
|
|
} |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* @param Container $container |
108
|
|
|
*/ |
109
|
|
|
public function setContainer(Container $container) { |
110
|
|
|
$this->container = $container; |
111
|
|
|
} |
112
|
|
|
} |
113
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.