From f529714f456fa1b511e6a5730e8baab04b405a61 Mon Sep 17 00:00:00 2001 From: Andy Dixon Date: Thu, 26 Feb 2026 11:36:17 +0000 Subject: [PATCH] docs: handle OAuth callback access_denied outcomes from stricter provider authz Update SDK docs and example callback handling to process provider callback errors explicitly. access_denied is now documented and handled as an expected authorization outcome (HTTP 403), including cases where provider membership/scope checks fail at consent submission. --- README.md | 1 + docs/INTEGRATION_GUIDE.md | 5 ++++- public_html/callback.php | 9 +++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c34c0c9..717210f 100644 --- a/README.md +++ b/README.md @@ -128,6 +128,7 @@ This wrapper now delegates to `BlackWall\Auth\AuthClient`. ## Security notes - Always validate OAuth `state` in callback handlers. +- Handle provider callback errors (`error`, `error_description`) explicitly; treat `access_denied` as an expected user/authorisation outcome rather than a transport failure. - For OIDC providers, include a per-request `nonce` in authorisation requests. - Always use HTTPS in production. - Store refresh tokens securely. diff --git a/docs/INTEGRATION_GUIDE.md b/docs/INTEGRATION_GUIDE.md index eff61a5..4b80f1f 100644 --- a/docs/INTEGRATION_GUIDE.md +++ b/docs/INTEGRATION_GUIDE.md @@ -63,8 +63,11 @@ $client = new AuthClient(Config::fromArray([ ])); if (isset($_GET['error'])) { + $error = (string) $_GET['error']; $description = isset($_GET['error_description']) ? (string) $_GET['error_description'] : 'Unknown provider error'; - http_response_code(400); + // access_denied is a normal authorisation outcome (for example, membership + // revoked or user denied consent between request and submit). + http_response_code($error === 'access_denied' ? 403 : 400); exit('Authorization failed: ' . $description); } diff --git a/public_html/callback.php b/public_html/callback.php index 39a6d61..6df4fee 100644 --- a/public_html/callback.php +++ b/public_html/callback.php @@ -25,6 +25,15 @@ $auth = new BlackWallAuth([ 'redirectUri' => 'https://test.dixon.cx/callback.php', ]); +if (isset($_GET['error'])) { + $error = (string) $_GET['error']; + $description = isset($_GET['error_description']) ? (string) $_GET['error_description'] : 'Authorisation was denied.'; + $status = $error === 'access_denied' ? 403 : 400; + http_response_code($status); + echo 'Authorisation failed: ' . htmlspecialchars($description, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); + exit; +} + try { $result = $auth->handleCallback($_GET); $_SESSION['access_token'] = $result['tokens']['access_token'] ?? null;