From 6caba6ff5466958700cbd7282766cec8f4136954 Mon Sep 17 00:00:00 2001 From: Akhil Date: Mon, 8 Apr 2024 09:03:14 +0530 Subject: [PATCH 1/5] Add bearer token patch --- patches/034-oidc-bearer-token-auth.patch | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 patches/034-oidc-bearer-token-auth.patch diff --git a/patches/034-oidc-bearer-token-auth.patch b/patches/034-oidc-bearer-token-auth.patch new file mode 100644 index 00000000..3ef85d79 --- /dev/null +++ b/patches/034-oidc-bearer-token-auth.patch @@ -0,0 +1,19 @@ +--- ../patches/CORSMiddleware.php 2024-04-08 08:53:20.410444998 +0530 ++++ ../patches/CORSMiddleware-new.php 2024-04-08 09:00:48.857350421 +0530 +@@ -93,6 +93,16 @@ + (!$this->hasAnnotationOrAttribute($reflectionMethod, 'PublicPage', PublicPage::class) || $this->session->isLoggedIn())) { + $user = array_key_exists('PHP_AUTH_USER', $this->request->server) ? $this->request->server['PHP_AUTH_USER'] : null; + $pass = array_key_exists('PHP_AUTH_PW', $this->request->server) ? $this->request->server['PHP_AUTH_PW'] : null; ++ ++ $appManager = \OC::$server->get(\OCP\App\IAppManager::class); ++ if ($appManager->isEnabledForUser('oidc_login')) { ++ $loginService = \OC::$server->get(OCA\OIDCLogin\Service\LoginService::class); ++ $authHeader = $this->request->getHeader('Authorization'); ++ $bearerToken = substr($authHeader, 7); ++ if ($this->request->getHeader('OIDC-LOGIN-WITH-TOKEN') === 'true' && $loginService->loginWithBearerToken($bearerToken)) { ++ return; ++ } ++ } + + // Allow to use the current session if a CSRF token is provided + if ($this->request->passesCSRFCheck()) { -- GitLab From af90ee58716b454b56eb3d98ab28aaa2a32a15e8 Mon Sep 17 00:00:00 2001 From: Akhil Date: Mon, 8 Apr 2024 17:53:31 +0530 Subject: [PATCH 2/5] Check is_oidc in session --- patches/034-oidc-bearer-token-auth.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/patches/034-oidc-bearer-token-auth.patch b/patches/034-oidc-bearer-token-auth.patch index 3ef85d79..5f8e37b1 100644 --- a/patches/034-oidc-bearer-token-auth.patch +++ b/patches/034-oidc-bearer-token-auth.patch @@ -17,3 +17,16 @@ // Allow to use the current session if a CSRF token is provided if ($this->request->passesCSRFCheck()) { +--- CORSMiddleware.php 2024-04-08 08:53:20.410444998 +0530 ++++ CORSMiddleware-new.php 2024-04-08 17:49:15.942402353 +0530 +@@ -93,6 +93,10 @@ + (!$this->hasAnnotationOrAttribute($reflectionMethod, 'PublicPage', PublicPage::class) || $this->session->isLoggedIn())) { + $user = array_key_exists('PHP_AUTH_USER', $this->request->server) ? $this->request->server['PHP_AUTH_USER'] : null; + $pass = array_key_exists('PHP_AUTH_PW', $this->request->server) ? $this->request->server['PHP_AUTH_PW'] : null; ++ ++ if ($this->session->getSession() instanceof ISession && $this->session->getSession()->exists('is_oidc')) { ++ return; ++ } + + // Allow to use the current session if a CSRF token is provided + if ($this->request->passesCSRFCheck()) { -- GitLab From 3febc627d6f5e7f33e1718bd42354b8d255d38e8 Mon Sep 17 00:00:00 2001 From: Akhil Date: Tue, 9 Apr 2024 19:11:21 +0530 Subject: [PATCH 3/5] Perform OIDC bearer token validation for CORs routes even when session is set --- patches/034-oidc-bearer-token-auth.patch | 37 ++++++++++-------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/patches/034-oidc-bearer-token-auth.patch b/patches/034-oidc-bearer-token-auth.patch index 5f8e37b1..f9a410be 100644 --- a/patches/034-oidc-bearer-token-auth.patch +++ b/patches/034-oidc-bearer-token-auth.patch @@ -1,32 +1,25 @@ ---- ../patches/CORSMiddleware.php 2024-04-08 08:53:20.410444998 +0530 -+++ ../patches/CORSMiddleware-new.php 2024-04-08 09:00:48.857350421 +0530 -@@ -93,6 +93,16 @@ +--- lib/private/AppFramework/Middleware/Security/CORSMiddleware.php 2024-04-08 08:53:20.410444998 +0530 ++++ lib/private/AppFramework/Middleware/Security/CORSMiddleware-new.php 2024-04-09 19:05:21.133629632 +0530 +@@ -93,6 +93,22 @@ (!$this->hasAnnotationOrAttribute($reflectionMethod, 'PublicPage', PublicPage::class) || $this->session->isLoggedIn())) { $user = array_key_exists('PHP_AUTH_USER', $this->request->server) ? $this->request->server['PHP_AUTH_USER'] : null; $pass = array_key_exists('PHP_AUTH_PW', $this->request->server) ? $this->request->server['PHP_AUTH_PW'] : null; + -+ $appManager = \OC::$server->get(\OCP\App\IAppManager::class); -+ if ($appManager->isEnabledForUser('oidc_login')) { -+ $loginService = \OC::$server->get(OCA\OIDCLogin\Service\LoginService::class); -+ $authHeader = $this->request->getHeader('Authorization'); -+ $bearerToken = substr($authHeader, 7); -+ if ($this->request->getHeader('OIDC-LOGIN-WITH-TOKEN') === 'true' && $loginService->loginWithBearerToken($bearerToken)) { ++ $authHeader = $this->request->getHeader('Authorization'); ++ $bearerToken = substr($authHeader, 7); ++ $appManager = \OC::$server->get(OCP\App\IAppManager); ++ ++ if ($this->session->getSession() instanceof ISession && $this->session->getSession()->exists('is_oidc') ++ && $appManager->isEnabledForUser('oidc_login') && $this->request->getHeader('OIDC-LOGIN-WITH-TOKEN') === 'true' && !empty($bearerToken)) { ++ try { ++ $loginService = \OC::$server->get(OCA\OIDCLogin\Service\LoginService::class); ++ $loginService->loginWithBearerToken($bearerToken); ++ $this->session->set('is_oidc', 1); + return; ++ } catch (\Exception $e) { ++ $this->logger->debug("WebDAV bearer token validation failed with: {$e->getMessage()}", $this->context); + } + } // Allow to use the current session if a CSRF token is provided if ($this->request->passesCSRFCheck()) { ---- CORSMiddleware.php 2024-04-08 08:53:20.410444998 +0530 -+++ CORSMiddleware-new.php 2024-04-08 17:49:15.942402353 +0530 -@@ -93,6 +93,10 @@ - (!$this->hasAnnotationOrAttribute($reflectionMethod, 'PublicPage', PublicPage::class) || $this->session->isLoggedIn())) { - $user = array_key_exists('PHP_AUTH_USER', $this->request->server) ? $this->request->server['PHP_AUTH_USER'] : null; - $pass = array_key_exists('PHP_AUTH_PW', $this->request->server) ? $this->request->server['PHP_AUTH_PW'] : null; -+ -+ if ($this->session->getSession() instanceof ISession && $this->session->getSession()->exists('is_oidc')) { -+ return; -+ } - - // Allow to use the current session if a CSRF token is provided - if ($this->request->passesCSRFCheck()) { -- GitLab From 006603eef1c454aa9db201d06a64cee6b903d256 Mon Sep 17 00:00:00 2001 From: Akhil Date: Tue, 9 Apr 2024 19:13:02 +0530 Subject: [PATCH 4/5] Change order of checks --- patches/034-oidc-bearer-token-auth.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/034-oidc-bearer-token-auth.patch b/patches/034-oidc-bearer-token-auth.patch index f9a410be..e793783b 100644 --- a/patches/034-oidc-bearer-token-auth.patch +++ b/patches/034-oidc-bearer-token-auth.patch @@ -10,7 +10,7 @@ + $appManager = \OC::$server->get(OCP\App\IAppManager); + + if ($this->session->getSession() instanceof ISession && $this->session->getSession()->exists('is_oidc') -+ && $appManager->isEnabledForUser('oidc_login') && $this->request->getHeader('OIDC-LOGIN-WITH-TOKEN') === 'true' && !empty($bearerToken)) { ++ && $this->request->getHeader('OIDC-LOGIN-WITH-TOKEN') === 'true' && !empty($bearerToken) && $appManager->isEnabledForUser('oidc_login') ) { + try { + $loginService = \OC::$server->get(OCA\OIDCLogin\Service\LoginService::class); + $loginService->loginWithBearerToken($bearerToken); -- GitLab From 8d03ddfb2b9be52d65ba620619fbd6234d02d282 Mon Sep 17 00:00:00 2001 From: Akhil Date: Fri, 12 Apr 2024 17:34:40 +0530 Subject: [PATCH 5/5] Use is_oidc_token_login and session check --- Dockerfile | 20 +++++++++------- patches/034-oidc-bearer-token-auth.patch | 30 +++++++----------------- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5883ce4f..b393155a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -205,6 +205,16 @@ ARG LDAP_WRITE_SUPPORT_VERSION="1.9.0" ARG OIDC_LOGIN_VERSION="3.0.2" ARG IS_SELFHOST=false +RUN curl -fsSL -o ldap_write_support.tar.gz \ + "https://github.com/nextcloud-releases/ldap_write_support/releases/download/v${LDAP_WRITE_SUPPORT_VERSION}/ldap_write_support-v${LDAP_WRITE_SUPPORT_VERSION}.tar.gz" && \ + tar -xf ldap_write_support.tar.gz -C ${BASE_DIR}/custom_apps && \ + rm ldap_write_support.tar.gz + +RUN curl -fsSL -o oidc_login.tar.gz \ + "https://github.com/pulsejet/nextcloud-oidc-login/releases/download/v${OIDC_LOGIN_VERSION}/oidc_login.tar.gz" && \ + tar -xf oidc_login.tar.gz -C ${BASE_DIR}/custom_apps && \ + rm oidc_login.tar.gz + # Patches COPY patches/ ${TMP_PATCH_DIR}/ RUN patch -u ${BASE_DIR}/core/templates/layout.user.php -i ${TMP_PATCH_DIR}/003-contact-search-removal.patch @@ -218,17 +228,9 @@ RUN patch -u ${BASE_DIR}/apps/dav/lib/Connector/Sabre/Principal.php -i ${TMP_PAT RUN patch -u ${BASE_DIR}/apps/dav/lib/HookManager.php -i ${TMP_PATCH_DIR}/028-default-task-calendar.patch RUN patch -u ${BASE_DIR}/apps/provisioning_api/lib/Controller/UsersController.php -i ${TMP_PATCH_DIR}/029-restrict-user-to-change-primary-email.patch RUN patch -u ${BASE_DIR}/lib/private/Security/VerificationToken/VerificationToken.php -i ${TMP_PATCH_DIR}/033-verification-token-private.patch +RUN patch -u ${BASE_DIR}/lib/private/AppFramework/Middleware/Security/CORSMiddleware.php -i ${TMP_PATCH_DIR}/034-oidc-bearer-token-auth.patch RUN rm -rf ${TMP_PATCH_DIR} -RUN curl -fsSL -o ldap_write_support.tar.gz \ - "https://github.com/nextcloud-releases/ldap_write_support/releases/download/v${LDAP_WRITE_SUPPORT_VERSION}/ldap_write_support-v${LDAP_WRITE_SUPPORT_VERSION}.tar.gz" && \ - tar -xf ldap_write_support.tar.gz -C ${BASE_DIR}/custom_apps && \ - rm ldap_write_support.tar.gz - -RUN curl -fsSL -o oidc_login.tar.gz \ - "https://github.com/pulsejet/nextcloud-oidc-login/releases/download/v${OIDC_LOGIN_VERSION}/oidc_login.tar.gz" && \ - tar -xf oidc_login.tar.gz -C ${BASE_DIR}/custom_apps && \ - rm oidc_login.tar.gz # Remove user avatar generation for system addressbook card RUN sed -i 's/$this->getAvatarImage($user)/null/' ${BASE_DIR}/apps/dav/lib/CardDAV/Converter.php diff --git a/patches/034-oidc-bearer-token-auth.patch b/patches/034-oidc-bearer-token-auth.patch index e793783b..51bd0156 100644 --- a/patches/034-oidc-bearer-token-auth.patch +++ b/patches/034-oidc-bearer-token-auth.patch @@ -1,25 +1,13 @@ --- lib/private/AppFramework/Middleware/Security/CORSMiddleware.php 2024-04-08 08:53:20.410444998 +0530 +++ lib/private/AppFramework/Middleware/Security/CORSMiddleware-new.php 2024-04-09 19:05:21.133629632 +0530 -@@ -93,6 +93,22 @@ - (!$this->hasAnnotationOrAttribute($reflectionMethod, 'PublicPage', PublicPage::class) || $this->session->isLoggedIn())) { - $user = array_key_exists('PHP_AUTH_USER', $this->request->server) ? $this->request->server['PHP_AUTH_USER'] : null; - $pass = array_key_exists('PHP_AUTH_PW', $this->request->server) ? $this->request->server['PHP_AUTH_PW'] : null; -+ -+ $authHeader = $this->request->getHeader('Authorization'); -+ $bearerToken = substr($authHeader, 7); -+ $appManager = \OC::$server->get(OCP\App\IAppManager); -+ -+ if ($this->session->getSession() instanceof ISession && $this->session->getSession()->exists('is_oidc') -+ && $this->request->getHeader('OIDC-LOGIN-WITH-TOKEN') === 'true' && !empty($bearerToken) && $appManager->isEnabledForUser('oidc_login') ) { -+ try { -+ $loginService = \OC::$server->get(OCA\OIDCLogin\Service\LoginService::class); -+ $loginService->loginWithBearerToken($bearerToken); -+ $this->session->set('is_oidc', 1); -+ return; -+ } catch (\Exception $e) { -+ $this->logger->debug("WebDAV bearer token validation failed with: {$e->getMessage()}", $this->context); -+ } -+ } - +@@ -97,6 +97,10 @@ // Allow to use the current session if a CSRF token is provided if ($this->request->passesCSRFCheck()) { + return; ++ } ++ // Skip CORS check for requests with oidc token auth. ++ if ($this->session->getSession() instanceof ISession && $this->session->getSession()->get('is_oidc_token_login') === 1) { ++ return; + } + // Skip CORS check for requests with AppAPI auth. + if ($this->session->getSession() instanceof ISession && $this->session->getSession()->get('app_api') === true) { -- GitLab