Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for custom authorization header and skip canary check #158

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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**. ⚠⚠

Expand All @@ -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

Expand Down
58 changes: 32 additions & 26 deletions lib/basicauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand All @@ -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
))
);
Expand Down