ILIAS  release_6 Revision v6.24-5-g0c8bfefb3b8
class.ilWebAccessChecker.php
Go to the documentation of this file.
1<?php
18// declare(strict_types=1);
22use Psr\Http\Message\UriInterface;
23
24require_once('./Services/WebAccessChecker/classes/class.ilWACSignedPath.php');
25require_once('./Services/WebAccessChecker/classes/class.ilWACPath.php');
26require_once('./Services/WebAccessChecker/classes/class.ilWACSecurePath.php');
27require_once('./Services/Init/classes/class.ilInitialisation.php');
28require_once('./Services/FileDelivery/classes/class.ilFileDelivery.php');
29
37{
38 const DISPOSITION = 'disposition';
39 const STATUS_CODE = 'status_code';
40 const REVALIDATE = 'revalidate';
41 const CM_FILE_TOKEN = 1;
42 const CM_FOLDER_TOKEN = 2;
44 const CM_SECFOLDER = 4;
48 protected $path_object = null;
52 protected $checked = false;
60 protected $override_mimetype = '';
64 protected $send_status_code = false;
68 protected $initialized = false;
72 protected $revalidate_folder_tokens = true;
76 protected static $use_seperate_logfile = false;
80 protected $applied_checking_methods = array();
84 private $http;
89
90
98 {
99 $this->setPathObject(new ilWACPath($httpState->request()->getRequestTarget()));
100 $this->http = $httpState;
101 $this->cookieFactory = $cookieFactory;
102 }
103
104
109 public function check()
110 {
111 if (!$this->getPathObject()) {
113 }
114
115 // Check if Path has been signed with a token
116 $ilWACSignedPath = new ilWACSignedPath($this->getPathObject(), $this->http, $this->cookieFactory);
117 if ($ilWACSignedPath->isSignedPath()) {
118 $this->addAppliedCheckingMethod(self::CM_FILE_TOKEN);
119 if ($ilWACSignedPath->isSignedPathValid()) {
120 $this->setChecked(true);
121 $this->sendHeader('checked using token');
122
123 return true;
124 }
125 }
126
127 // Check if the whole secured folder has been signed
128 if ($ilWACSignedPath->isFolderSigned()) {
129 $this->addAppliedCheckingMethod(self::CM_FOLDER_TOKEN);
130 if ($ilWACSignedPath->isFolderTokenValid()) {
131 if ($this->isRevalidateFolderTokens()) {
132 $ilWACSignedPath->revalidatingFolderToken();
133 }
134 $this->setChecked(true);
135 $this->sendHeader('checked using secure folder');
136
137 return true;
138 }
139 }
140
141 // Fallback, have to initiate ILIAS
142 $this->initILIAS();
143
144 // Check if Path is within accepted paths
145 if ($this->getPathObject()->getModuleType() !== 'rs') {
146 $path = realpath($this->getPathObject()->getCleanURLdecodedPath());
147 $data_dir = realpath(CLIENT_WEB_DIR);
148 if (strpos($path, $data_dir) !== 0) {
149 return false;
150 }
151 if (dirname($path) === $data_dir && is_file($path)) {
152 return false;
153 }
154 }
155
157 // Maybe the path has been registered, lets check
158 $checkingInstance = ilWACSecurePath::getCheckingInstance($this->getPathObject());
159 $this->addAppliedCheckingMethod(self::CM_CHECKINGINSTANCE);
160 $canBeDelivered = $checkingInstance->canBeDelivered($this->getPathObject());
161 if ($canBeDelivered) {
162 $this->sendHeader('checked using fallback');
163 if ($ilWACSignedPath->isFolderSigned() && $this->isRevalidateFolderTokens()) {
164 $ilWACSignedPath->revalidatingFolderToken();
165 }
166
167 $this->setChecked(true);
168
169 return true;
170 } else {
171 $this->setChecked(true);
172
173 return false;
174 }
175 }
176
177 // none of the checking mechanisms could have been applied. no access
178 $this->setChecked(true);
179 if ($this->getPathObject()->isInSecFolder()) {
180 $this->addAppliedCheckingMethod(self::CM_SECFOLDER);
181
182 return false;
183 } else {
184 $this->addAppliedCheckingMethod(self::CM_SECFOLDER);
185
186 return true;
187 }
188 }
189
190
196 protected function sendHeader($message)
197 {
198 $response = $this->http->response()->withHeader('X-ILIAS-WebAccessChecker', $message);
199 $this->http->saveResponse($response);
200 }
201
202
206 public function initILIAS()
207 {
208 if ($this->isInitialized()) {
209 return;
210 }
211
212 $GLOBALS['COOKIE_PATH'] = '/';
213
214 $cookie = $this->cookieFactory->create('ilClientId', $this->getPathObject()->getClient())
215 ->withPath('/')
216 ->withExpires(0);
217
218 $response = $this->http->cookieJar()
219 ->with($cookie)
220 ->renderIntoResponseHeader($this->http->response());
221
222 $this->http->saveResponse($response);
223
225 try {
227 $this->checkUser();
228 $this->checkPublicSection();
229 } catch (Exception $e) {
230 if ($e instanceof ilWACException
231 && $e->getCode() !== ilWACException::ACCESS_DENIED_NO_LOGIN) {
232 throw $e;
233 }
234 if (($e instanceof Exception && $e->getMessage() == 'Authentication failed.')
235 || $e->getCode() === ilWACException::ACCESS_DENIED_NO_LOGIN) {
236 $this->initAnonymousSession();
237 $this->checkUser();
238 $this->checkPublicSection();
239 }
240 }
241 $this->setInitialized(true);
242 }
243
244
249 protected function checkPublicSection()
250 {
251 global $DIC;
252 $on_login_page = !$this->isRequestNotFromLoginPage();
253 $is_anonymous = ((int) $DIC->user()->getId() === (int) ANONYMOUS_USER_ID);
254 $is_null_user = ($DIC->user()->getId() === 0);
255 $pub_section_activated = (bool) $DIC['ilSetting']->get('pub_section');
256 $isset = isset($DIC['ilSetting']);
257 $instanceof = $DIC['ilSetting'] instanceof ilSetting;
258
259 if (!$isset || !$instanceof) {
261 }
262
263 if ($on_login_page && ($is_null_user || $is_anonymous)) {
264 // Request is initiated from login page
265 return;
266 }
267
268 if ($pub_section_activated && ($is_null_user || $is_anonymous)) {
269 // Request is initiated from an enabled public area
270 return;
271 }
272
273 if ($is_anonymous || $is_null_user) {
275 }
276 }
277
278
279 protected function checkUser()
280 {
281 global $DIC;
282
283 $is_user = $DIC->user() instanceof ilObjUser;
284 $user_id_is_zero = ((int) $DIC->user()->getId() === 0);
285 $not_on_login_page = $this->isRequestNotFromLoginPage();
286 if (!$is_user || ($user_id_is_zero && $not_on_login_page)) {
288 }
289 }
290
291
295 public function isChecked()
296 {
297 return (bool) $this->checked;
298 }
299
300
306 public function setChecked($checked)
307 {
308 assert(is_bool($checked));
309 $this->checked = $checked;
310 }
311
312
316 public function getPathObject()
317 {
318 return $this->path_object;
319 }
320
321
328 {
329 $this->path_object = $path_object;
330 }
331
332
336 public function getDisposition()
337 {
338 return (string) $this->disposition;
339 }
340
341
348 {
349 assert(is_string($disposition));
350 $this->disposition = $disposition;
351 }
352
353
357 public function getOverrideMimetype()
358 {
359 return (string) $this->override_mimetype;
360 }
361
362
369 {
370 assert(is_string($override_mimetype));
371 $this->override_mimetype = $override_mimetype;
372 }
373
374
378 public function isInitialized()
379 {
380 return (bool) $this->initialized;
381 }
382
383
388 {
389 assert(is_bool($initialized));
390 $this->initialized = $initialized;
391 }
392
393
397 public function isSendStatusCode()
398 {
399 return (bool) $this->send_status_code;
400 }
401
402
409 {
410 assert(is_bool($send_status_code));
411 $this->send_status_code = $send_status_code;
412 }
413
414
418 public function isRevalidateFolderTokens()
419 {
421 }
422
423
430 {
431 assert(is_bool($revalidate_folder_tokens));
432 $this->revalidate_folder_tokens = $revalidate_folder_tokens;
433 }
434
435
439 public static function isUseSeperateLogfile()
440 {
441 return (bool) self::$use_seperate_logfile;
442 }
443
444
451 {
452 assert(is_bool($use_seperate_logfile));
453 self::$use_seperate_logfile = $use_seperate_logfile;
454 }
455
456
461 {
462 return (array) $this->applied_checking_methods;
463 }
464
465
472 {
473 $this->applied_checking_methods = $applied_checking_methods;
474 }
475
476
482 protected function addAppliedCheckingMethod($method)
483 {
484 assert(is_int($method));
485 $this->applied_checking_methods[] = $method;
486 }
487
488
489 protected function initAnonymousSession()
490 {
491 global $DIC;
492 include_once './Services/Context/classes/class.ilContext.php';
493 session_destroy();
495 require_once("Services/Init/classes/class.ilInitialisation.php");
500 $ilAuthSession = $DIC['ilAuthSession'];
501 $ilAuthSession->init();
502 $ilAuthSession->regenerateId();
503 $a_id = (int) ANONYMOUS_USER_ID;
504 $ilAuthSession->setUserId($a_id);
505 $ilAuthSession->setAuthenticated(false, $a_id);
506 $DIC->user()->setId($a_id);
507 }
508
509
513 protected function isRequestNotFromLoginPage()
514 {
515 $referrer = (string) ($_SERVER['HTTP_REFERER'] ?? '');
516 $not_on_login_page = (strpos($referrer, 'login.php') === false
517 && strpos($referrer, '&baseClass=ilStartUpGUI') === false);
518
519 if ($not_on_login_page && $referrer !== '') {
520 // In some scenarios (observed for content styles on login page, the HTTP_REFERER does not contain a PHP script
521 $referrer_url_parts = parse_url($referrer);
522 $ilias_url_parts = parse_url(ilUtil::_getHttpPath());
523 if (
524 $ilias_url_parts['host'] === $referrer_url_parts['host'] &&
525 (
526 !isset($referrer_url_parts['path']) ||
527 strpos($referrer_url_parts['path'], '.php') === false
528 )
529 ) {
530 $not_on_login_page = false;
531 }
532 }
533
534 return $not_on_login_page;
535 }
536}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
An exception for terminatinating execution or to throw for unit testing.
static init($a_type)
Init context by type.
const CONTEXT_WAC
static initILIAS()
ilias initialisation
ILIAS Setting Class.
static _getHttpPath()
Class ilWACException.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static hasCheckingInstanceRegistered(ilWACPath $ilWACPath)
Searches a checking instance for the given wac path.
Class ilWACSignedPath.
Class ilWebAccessChecker.
__construct(GlobalHttpState $httpState, CookieFactory $cookieFactory)
ilWebAccessChecker constructor.
static setUseSeperateLogfile($use_seperate_logfile)
setSendStatusCode($send_status_code)
setRevalidateFolderTokens($revalidate_folder_tokens)
setAppliedCheckingMethods(array $applied_checking_methods)
setPathObject(ilWACPath $path_object)
setOverrideMimetype($override_mimetype)
Interface GlobalHttpState.
request()
Returns the current psr-7 server request.
static http()
Fetches the global http state from ILIAS.
$response
$_SERVER['HTTP_HOST']
Definition: raiseError.php:10
$message
Definition: xapiexit.php:14
$DIC
Definition: xapitoken.php:46