{"record":{"id":"68cbd29d0c373bde","repo":"passbolt/passbolt_api","slug":"error","errorCode":null,"errorMessage":"error","messagePattern":"error","errorType":"http","errorClass":"AdfsException","httpStatus":null,"severity":"error","filePath":"plugins/PassboltEe/Sso/src/Utility/Adfs/Provider/AdfsProvider.php","lineNumber":60,"sourceCode":"     * @inheritDoc\n     */\n    public function __construct(array $options = [], array $collaborators = [])\n    {\n        $options['emailClaim'] = $options['emailClaim'] ?? $this->emailClaim;\n\n        parent::__construct($options, $collaborators);\n    }\n\n    /**\n     * @inheritDoc\n     */\n    protected function checkResponse(ResponseInterface $response, $data): void\n    {\n        try {\n            parent::checkResponse($response, $data);\n        } catch (OAuth2Exception $e) {\n            // Map OAuth2 exception with ADFS exception\n            throw new AdfsException($data['error'], $data['error_description']);\n        }\n    }\n\n    /**\n     * @inheritDoc\n     */\n    protected function createResourceOwner(array $response, AccessToken $token): ResourceOwnerInterface\n    {\n        return new AdfsResourceOwner($response, $this->emailClaim);\n    }\n}\n","sourceCodeStart":42,"sourceCodeEnd":72,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Sso/src/Utility/Adfs/Provider/AdfsProvider.php#L42-L72","documentation":"AdfsProvider::checkResponse() overrides the OAuth2 base provider: when the token endpoint returns an error payload, the base checkResponse throws OAuth2Exception, which is re-mapped to AdfsException carrying the raw ADFS `error` code and `error_description`. The message shown ('error') is literally the value ADFS returned in the `error` field.","triggerScenarios":"Exchanging the authorization code at the ADFS token endpoint when ADFS responds with an error body, e.g. invalid_grant (expired/used code), invalid_client, or redirect_uri mismatch.","commonSituations":"ADFS server clock skew making codes appear expired; user clicking Back and replaying the code; wrong client_id/secret configured in passbolt SSO settings; redirect URI registered in ADFS differing from the configured one; ADFS farm misconfiguration.","solutions":["Read error_description in the exception/log for ADFS's specific reason","Verify client_id, client_secret and redirect_uri in passbolt SSO settings exactly match the ADFS Application Group","Re-start the SSO flow — authorization codes are single-use and short-lived","Check ADFS server time (NTP) and that the relying party trust is configured correctly"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// validate SSO settings before initiating: client id/secret/redirect uri non-empty and matching ADFS registration","typeGuard":null,"tryCatchPattern":"try { $token = $provider->getAccessToken('authorization_code', ['code' => $code]); } catch (AdfsException $e) { Log::warning('ADFS error: ' . $e->getMessage() . ' - ' . $e->getDescription()); return redirect('/sso/restart'); }","preventionTips":["Restart the flow on any token-exchange error (codes are single-use)","Keep ADFS client registration and passbolt SSO settings in sync","Sync ADFS server clocks with NTP"],"tags":["sso","adfs","oauth2","token-exchange"],"backgroundTag":"oauth-token-exchange-failed","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"}