-
Notifications
You must be signed in to change notification settings - Fork 0
/
ADFSVerificationService.php
150 lines (144 loc) · 4.65 KB
/
ADFSVerificationService.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
<?php
namespace oshco\adfs;
use oshco\adfs\ADFSResponse;
use oshco\adfs\ADFSUser;
use webfiori\http\AbstractWebService;
use webfiori\http\Response;
/**
* A class that contains the implementation of the service which is used to
* verify the status of ADFS response.
*/
abstract class ADFSVerificationService extends AbstractWebService {
/**
*
* @var ADFSResponse
*/
private $samlResponse;
/**
* Creates new instance of the class.
*
* @param string $name The name of the service.
* @param string $failRedirect A URL at which the user will be redirected to in case of ADFS login fail.
*/
public function __construct(string $name = 'verify', string $failRedirect = '') {
parent::__construct($name);
$this->addRequestMethod('POST');
$this->addRequestMethod('GET');
$this->addParameters([
'SAMLResponse' => [
'type' => 'string'
]
]);
$this->setOnFailRedirect($failRedirect);
$this->setFailStatus('');
}
/**
* Returns a user given its username.
*
* The username of the user will be taken from ADFS response as received.
* The method must be implemented in a way that it looks for such user
* in the application's database which has provided username/email and
* return its information as an object of type 'oshco\adfs\ADFSUser'.
* If no such user was found, null should be returned.
*
* @return ADFSUser|null
*/
public abstract function getUser(string $username);
/**
* Send the response to the callback which was set when ADFS authentication
* fails.
*
* The method will send a response with code 401 to the URL which was set
* on failure. Additionally, the URL will have extra parameter at the
* end which hold status code of the failure with name 'status'.
*
* @param ADFSUser|null $user
*/
public function onFail(ADFSUser $user = null) {
Response::addHeader('location', $this->getOnFailRedirect().'?status='. urlencode($this->getFailStatus()));
Response::setCode(401);
Response::send();
}
/**
* Execute the instructions in case of ADFS success.
*
* This method must be implemented in a way that it executes a set of
* instructions when ADFS returns a success status.
*
* @param ADFSUser The user who was signed in using ADFS.
*/
public abstract function onSuccess(ADFSUser $user);
private $failStatus;
/**
* Returns a string that represents ADFS fail status.
*
* @return string Default return value is empty string.
*/
public function getFailStatus() : string {
return $this->failStatus;
}
/**
* Returns a string that represents ADFS fail redirect URL.
*
* @return string Default return value is the base URL of the application.
*/
public function getOnFailRedirect() : string {
return $this->onFailRedirect;
}
/**
* Sets a string to use as status code for ADFS failure.
*
* @param string $failStatus
*/
public function setFailStatus(string $failStatus) {
$this->failStatus = $failStatus;
}
private $onFailRedirect;
/**
* Sets a URL that the response will be redirected to in case of ADFS failure.
*
* @param string $url
*/
public function setOnFailRedirect(string $url) {
$this->onFailRedirect = $url;
}
/**
* Returns a string that represents the application name as set in ADFS configuration.
*
* The value of this property is set by ADFS server.
*
* @return string Default return value is empty string.
*/
public function getAppName() : string {
if ($this->samlResponse !== null) {
return $this->samlResponse->getAppName();
}
return '';
}
/**
* Returns SAML response that was received from ADFS server.
*
* @return ADFSResponse|null If set, it is returned as an object. Other than
* that, null is returned.
*/
public function getSamlResponse() {
return $this->samlResponse;
}
/**
* Process the request.
*/
public function processRequest() {
$this->samlResponse = new ADFSResponse($_POST['SAMLResponse']);
if ($this->getSamlResponse()->isSuccess()) {
$username = $this->getSamlResponse()->getUserName();
$user = $this->getUser($username);
if ($user === null) {
$this->onFail();
} else {
$this->onSuccess($user);
}
} else {
$this->onFail();
}
}
}