diff --git a/lib/Controller/SAMLController.php b/lib/Controller/SAMLController.php index 81b3a0083..0cabef22d 100644 --- a/lib/Controller/SAMLController.php +++ b/lib/Controller/SAMLController.php @@ -41,6 +41,7 @@ use OneLogin\Saml2\Auth; use OneLogin\Saml2\Error; use OneLogin\Saml2\Settings; +use OneLogin\Saml2\Utils; use OneLogin\Saml2\ValidationError; use Psr\Log\LoggerInterface; @@ -359,6 +360,8 @@ public function assertionConsumerService(): Http\RedirectResponse { return new Http\RedirectResponse($this->urlGenerator->getAbsoluteURL('/')); } + Utils::setBaseURLPath($this->urlGenerator->getWebroot()); + $auth = new Auth($this->samlSettings->getOneLoginSettingsArray($idp)); // validator (called with processResponse()) needs an XML entity loader $this->callWithXmlEntityLoader(function () use ($auth, $AuthNRequestID): void { diff --git a/tests/unit/Controller/SAMLControllerTest.php b/tests/unit/Controller/SAMLControllerTest.php index 8a40440cb..744dcbf3e 100644 --- a/tests/unit/Controller/SAMLControllerTest.php +++ b/tests/unit/Controller/SAMLControllerTest.php @@ -29,6 +29,7 @@ use OCP\IUserSession; use OCP\Security\ICrypto; use OCP\Security\ITrustedDomainHelper; +use OneLogin\Saml2\Utils; use Override; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\MockObject\MockObject; @@ -440,4 +441,50 @@ public function testLoginWithUnconfiguredIdpRedirectsToGenericError(): void { $this->assertInstanceOf(RedirectResponse::class, $result); $this->assertEquals($errorUrl, $result->getRedirectURL()); } + + public function testAssertionConsumerServiceSetsSamlBaseUrlPath(): void { + try { + Utils::setBaseURLPath(''); + + $this->urlGenerator + ->expects($this->once()) + ->method('getWebroot') + ->willReturn('/nextcloud'); + + $data = [ + 'AuthNRequestID' => 'request-id', + 'Idp' => 1, + 'OriginalUrl' => '', + ]; + + $this->request + ->expects($this->once()) + ->method('getCookie') + ->with('saml_data') + ->willReturn(base64_encode('encrypted-cookie')); + + $this->crypto + ->expects($this->once()) + ->method('decrypt') + ->with('encrypted-cookie') + ->willReturn(json_encode($data, JSON_THROW_ON_ERROR)); + + $this->samlSettings + ->expects($this->once()) + ->method('getOneLoginSettingsArray') + ->with(1) + ->willReturn([]); + + try { + $this->samlController->assertionConsumerService(); + } catch (\Throwable) { + // Auth initialization is expected to fail with the minimal + // SAML configuration used by this test. + } + + $this->assertSame('/nextcloud/', Utils::getBaseURLPath()); + } finally { + Utils::setBaseURLPath(''); + } + } }