{"record":{"id":"c61fed0bec356ef8","repo":"passbolt/passbolt_api","slug":"ajax-json-request-not-supported-ssosuccessdryruncontroller","errorCode":null,"errorMessage":"Ajax/Json request not supported.","messagePattern":"Ajax/Json request not supported\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Sso/src/Controller/Success/SsoSuccessDryRunController.php","lineNumber":32,"sourceCode":" * @link          https://www.passbolt.com Passbolt(tm)\n * @since         3.9.0\n */\n\nnamespace Passbolt\\Sso\\Controller\\Success;\n\nuse Cake\\Http\\Exception\\BadRequestException;\nuse Passbolt\\Sso\\Controller\\AbstractSsoController;\n\nclass SsoSuccessDryRunController extends AbstractSsoController\n{\n    /**\n     * @return void\n     * @throws \\League\\OAuth2\\Client\\Provider\\Exception\\IdentityProviderException\n     */\n    public function ssoSuccess(): void\n    {\n        if ($this->request->is('json')) {\n            throw new BadRequestException(__('Ajax/Json request not supported.'));\n        }\n\n        $this->User->assertIsAdmin();\n        $this->getTokenFromUrlQuery();\n\n        // Not much to do\n        $this->viewBuilder()\n            ->setLayout('default')\n            ->setTemplatePath('success')\n            ->setTemplate('stage3');\n    }\n}\n","sourceCodeStart":14,"sourceCodeEnd":45,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Sso/src/Controller/Success/SsoSuccessDryRunController.php#L14-L45","documentation":"ssoSuccess() is the browser-only OAuth2 redirect endpoint; it immediately rejects any request flagged as JSON/Ajax with BadRequestException. The SSO success flow expects a real HTTP redirect from the identity provider, not an API call.","triggerScenarios":"Calling GET /sso/success with the Accept: application/json header or the CakePHP ?_ext=json / JSON extensions enabled, e.g. when an API client or a browser extension forces JSON content negotiation.","commonSituations":"Developers testing the endpoint via Postman/curl with JSON accept headers; passbolt desktop/cli clients misconfigured to hit the web redirect URL; front-end code fetching the success URL instead of following the redirect in a browser window.","solutions":["Remove the JSON accept header / Ajax flags and open /sso/success in a regular browser navigation flow","Check client code is not using fetch/axios to call this URL; the URL should be the OAuth redirect target","If you need token exchange programmatically, use the dedicated SSO API endpoints instead of the success redirect endpoint"],"exampleFix":"// before\ncurl -H 'Accept: application/json' https://passbolt.example.com/sso/success\n// after\n# navigate in browser, no JSON header:\ncurl -L https://passbolt.example.com/sso/success","handlingStrategy":"validation","validationCode":"if (strpos($_SERVER['HTTP_ACCEPT'] ?? '', 'application/json') !== false) {\n    // do not call /sso/success via API; open in browser instead\n}","typeGuard":null,"tryCatchPattern":"try {\n    $resp = $httpClient->get($successUrl, ['headers' => ['Accept' => 'text/html']]);\n} catch (\\Passbolt\\WebInstaller\\Error\\Exception\\BadRequestException $e) {\n    // fall back to browser navigation\n}","preventionTips":["Never fetch the SSO success redirect URL with JSON-accepting HTTP clients","Keep OAuth callback navigation in a browser/webview","Use dedicated SSO API endpoints for programmatic flows"],"tags":["http","sso","bad-request","content-negotiation"],"backgroundTag":"unsupported-operation","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}