diff --git a/README.md b/README.md index 0bad94b..4b65625 100644 --- a/README.md +++ b/README.md @@ -139,11 +139,12 @@ BasicAuth Authenticate users by an [HTTP Basic access authentication][BasicAuth_0] call. HTTP server of your choice to authenticate. It should return HTTP 2xx for correct credentials and an appropriate other error code for wrong ones or refused access. -The HTTP server _must_ respond to any requests to the target URL with the "www-authenticate" header set. +By default, the HTTP server _must_ respond to any requests to the target URL with the "www-authenticate" header set. Otherwise BasicAuth considers itself to be misconfigured or the HTTP server unfit for authentication. +This check can be disabled by passing `true` as the third-argument. ### Configuration -The only supported parameter is the URL of the web server where the authentication happens. +The only mandatory parameter is the URL of the web server where the authentication happens. In addition, there are two optional parameters to configure the authorization header name (defaults to `authorization`) and a boolean to disable the `www-authenticate` header check (use with care!). **⚠⚠ Warning:** make sure to use the URL of a correctly configured HTTP Basic authenticating server. If the server always responds with a HTTP 2xx response without validating the users, this would allow anyone to log in to your Nextcloud instance with **any username / password combination**. ⚠⚠ @@ -156,6 +157,15 @@ Add the following to your `config.php`: ), ), +To use a different authorization header and disable the "www-authenticate" header check (for integration with Authelia for example), use the following: + + 'user_backends' => array( + array( + 'class' => 'OC_User_BasicAuth', + 'arguments' => array('https://authelia.example.com/api/verify', 'Proxy-Authorization', true), + ), + ), + [BasicAuth_0]: https://en.wikipedia.org/wiki/Basic_access_authentication diff --git a/lib/basicauth.php b/lib/basicauth.php index 5963972..9ee093b 100644 --- a/lib/basicauth.php +++ b/lib/basicauth.php @@ -9,10 +9,14 @@ class OC_User_BasicAuth extends \OCA\user_external\Base { private $authUrl; + private $authorizationHeader; + private $skipCanaryCheck; - public function __construct($authUrl) { + public function __construct($authUrl, $header = 'authorization', $skipCanary = false) { parent::__construct($authUrl); - $this->authUrl =$authUrl; + $this->authUrl = $authUrl; + $this->authorizationHeader = $header; + $this->skipCanaryCheck = $skipCanary; } /** @@ -24,36 +28,38 @@ public function __construct($authUrl) { * @return true/false */ public function checkPassword($uid, $password) { - /* - * Connect without user/name password to make sure - * URL is indeed authenticating or not... - */ - $context = stream_context_create(array( - 'http' => array( - 'method' => "GET", - 'follow_location' => 0 - )) - ); - $canary = get_headers($this->authUrl, 1, $context); - if(!$canary) { - OC::$server->getLogger()->error( - 'ERROR: Not possible to connect to BasicAuth Url: '.$this->authUrl, - ['app' => 'user_external'] + if (!$this->skipCanaryCheck) { + /* + * Connect without user/name password to make sure + * URL is indeed authenticating or not... + */ + $context = stream_context_create(array( + 'http' => array( + 'method' => "GET", + 'follow_location' => 0 + )) ); - return false; - } - if (!isset(array_change_key_case($canary, CASE_LOWER)['www-authenticate'])) { - OC::$server->getLogger()->error( - 'ERROR: Mis-configured BasicAuth Url: '.$this->authUrl.', provided URL does not do authentication!', - ['app' => 'user_external'] - ); - return false; + $canary = get_headers($this->authUrl, 1, $context); + if(!$canary) { + OC::$server->getLogger()->error( + 'ERROR: Not possible to connect to BasicAuth Url: '.$this->authUrl, + ['app' => 'user_external'] + ); + return false; + } + if (!isset(array_change_key_case($canary, CASE_LOWER)['www-authenticate'])) { + OC::$server->getLogger()->error( + 'ERROR: Mis-configured BasicAuth Url: '.$this->authUrl.', provided URL does not do authentication!', + ['app' => 'user_external'] + ); + return false; + } } $context = stream_context_create(array( 'http' => array( 'method' => "GET", - 'header' => "authorization: Basic " . base64_encode("$uid:$password"), + 'header' => $this->authorizationHeader . ": Basic " . base64_encode("$uid:$password"), 'follow_location' => 0 )) );