Description
** Nextcloud does not have internal support for client certificates being used for http authentication **
This is a problem when accessing the /settings/admin/overview page as it cannot connect to my server (403 error)
This is also a problem when integrating with 3rd party apps such as Collabora on my site (also protected with client certificates
** Proposed solution **
I have edited the Client.php file: /app/www/public/lib/private/Http/Client/Client.php to add support. The diff below will allow users to enable this in the main nextcloud config.php file and also specify a path to appropriate certificate, key, and if required, password for that key (all in pem format). It would be great if you could take a look at the diff and merge this into the code for nextcloud for an upcoming release as I've seen that others also desire this feature. Many thanks.
** Usage **
- change the /app/www/public/lib/private/Http/Client/Client.php file as shown below
- One of a or b
2a. copy the client ssl certificate to $SERVERROOT/config/client_ssl/cert.pem and the key to $SERVERROOT/config/client_ssl/key.pem
2b. edit config.php (for me: /config/www/nextcloud/config/config.php) to set the locaton for these files. e.g.
'internal_client_authentication_cert' => '/config/client_ssl/nextcloud_server_cert.pem',
'internal_client_authentication_key' => '/config/client_ssl/nextcloud_server_key.pem',
'internal_client_authentication_key_pass' => 'my password', - edit config.php (for me: /config/www/nextcloud/config/config.php) to enable client authentication support
'client_authentication_enabled' => true,
+++ Client.php
@@ -5,6 +5,8 @@
* SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2016 ownCloud, Inc.
* SPDX-License-Identifier: AGPL-3.0-only
+ *
+ * /app/www/public/lib/private/Http/Client/Client.php
*/
namespace OC\Http\Client;
@@ -80,6 +82,14 @@
$options = array_merge($defaults, $options);
+ if ($this->isClientAuthenticationEnabled($options)) {
+ $client_auth_options = [
+ RequestOptions::CERT => $this->getClientAuthenticationCert($options),
+ RequestOptions::SSL_KEY => $this->getClientAuthenticationKey($options),
+ ];
+ $options = array_merge($client_auth_options, $options);
+ }
+
if (!isset($options[RequestOptions::HEADERS]['User-Agent'])) {
$options[RequestOptions::HEADERS]['User-Agent'] = 'Nextcloud Server Crawler';
}
@@ -107,6 +117,37 @@
return $this->certificateManager->getAbsoluteBundlePath();
}
+
+ private function isClientAuthenticationEnabled(array $options): bool {
+ if (($options['nextcloud']['client_authentication_enabled'] ?? false) ||
+ $this->config->getSystemValueBool('client_authentication_enabled', false)) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private function getClientAuthenticationCert(array $options): ?string {
+ $clientCert = $this->config->getSystemValueString('internal_client_authentication_cert', \OC::$SERVERROOT . '/config/client_ssl/cert.pem');
+ if ($clientCert === '') {
+ return null;
+ }
+ return $clientCert;
+ }
+
+/* PHP8+ private function getClientAuthenticationKey(array $options): ?array|?string {*/
+ private function getClientAuthenticationKey(array $options) {
+ $clientKey = $this->config->getSystemValueString('internal_client_authentication_key', \OC::$SERVERROOT . '/config/client_ssl/key.pem');
+ $clientKeyPass = $this->config->getSystemValueString('internal_client_authentication_key_pass', '<not specified>');
+ if ($clientKey === '') {
+ return null;
+ }
+ if ($clientKeyPass === '<not specified>') {
+ return $clientKey;
+ } else {
+ return array($clientKey, $clientKeyPass);
+ }
+ }
/**
* Returns a null or an associative array specifying the proxy URI for```
**Here is the full file for your convenience:**
[Client.php.txt](https://github.com/user-attachments/files/19754845/Client.php.txt)