Challenge client on invalid basic access auth credentials

refs #9660
This commit is contained in:
Eric Lippmann 2015-07-30 13:59:18 +02:00
parent 42d698a6b3
commit c594d6db33
1 changed files with 42 additions and 7 deletions

View File

@ -33,6 +33,13 @@ class Auth
*/ */
protected $request; protected $request;
/**
* Response
*
* @var \Icinga\Web\Response
*/
protected $response;
/** /**
* Authenticated user * Authenticated user
* *
@ -185,6 +192,19 @@ class Auth
return $this->request; return $this->request;
} }
/**
* Get the response
*
* @return \Icinga\Web\Response
*/
public function getResponse()
{
if ($this->response === null) {
$this->response = Icinga::app()->getResponse();
}
return $this->response;
}
/** /**
* Get applied restrictions matching a given restriction name * Get applied restrictions matching a given restriction name
* *
@ -251,8 +271,7 @@ class Auth
/** /**
* Attempt to authenticate a user using HTTP authentication * Attempt to authenticate a user using HTTP authentication
* *
* Supports only the Basic HTTP authentication scheme. This will not challenge the client if authorization is * Supports only the Basic HTTP authentication scheme. XHR will be ignored.
* missing or invalid yet. XHR will be ignored.
* *
* @return bool * @return bool
*/ */
@ -261,20 +280,22 @@ class Auth
if ($this->getRequest()->isXmlHttpRequest()) { if ($this->getRequest()->isXmlHttpRequest()) {
return false; return false;
} }
$header = $this->getRequest()->getHeader('Authorization'); if (($header = $this->getRequest()->getHeader('Authorization')) === false) {
if (empty($header)) {
return false; return false;
} }
if (empty($header)) {
$this->challengeHttp();
}
list($scheme) = explode(' ', $header, 2); list($scheme) = explode(' ', $header, 2);
if ($scheme !== 'Basic') { if ($scheme !== 'Basic') {
return false; $this->challengeHttp();
} }
$authorization = substr($header, strlen('Basic ')); $authorization = substr($header, strlen('Basic '));
$credentials = base64_decode($authorization); $credentials = base64_decode($authorization);
$credentials = array_filter(explode(':', $credentials)); $credentials = array_filter(explode(':', $credentials));
if (count($credentials) !== 2) { if (count($credentials) !== 2) {
// Deny empty username and/or password // Deny empty username and/or password
return false; $this->challengeHttp();
} }
$user = new User($credentials[0]); $user = new User($credentials[0]);
$password = $credentials[1]; $password = $credentials[1];
@ -283,10 +304,24 @@ class Auth
$user->setIsHttpUser(true); $user->setIsHttpUser(true);
return true; return true;
} else { } else {
return false; $this->challengeHttp();
} }
} }
/**
* Challenge client immediately for HTTP authentication
*
* Sends the response w/ the 401 Unauthorized status code and WWW-Authenticate header.
*/
protected function challengeHttp()
{
$response = $this->getResponse();
$response->setHttpResponseCode(401);
$response->setHeader('WWW-Authenticate', 'Basic realm="Icinga Web 2"');
$response->sendHeaders();
exit();
}
/** /**
* Whether an authenticated user has a given permission * Whether an authenticated user has a given permission
* *