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.
This commit is contained in:
Andy Dixon
2026-02-26 11:36:17 +00:00
parent 6ddbcaec70
commit f529714f45
3 changed files with 14 additions and 1 deletions
+1
View File
@@ -128,6 +128,7 @@ This wrapper now delegates to `BlackWall\Auth\AuthClient`.
## Security notes ## Security notes
- Always validate OAuth `state` in callback handlers. - 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. - For OIDC providers, include a per-request `nonce` in authorisation requests.
- Always use HTTPS in production. - Always use HTTPS in production.
- Store refresh tokens securely. - Store refresh tokens securely.
+4 -1
View File
@@ -63,8 +63,11 @@ $client = new AuthClient(Config::fromArray([
])); ]));
if (isset($_GET['error'])) { if (isset($_GET['error'])) {
$error = (string) $_GET['error'];
$description = isset($_GET['error_description']) ? (string) $_GET['error_description'] : 'Unknown provider 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); exit('Authorization failed: ' . $description);
} }
+9
View File
@@ -25,6 +25,15 @@ $auth = new BlackWallAuth([
'redirectUri' => 'https://test.dixon.cx/callback.php', '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 { try {
$result = $auth->handleCallback($_GET); $result = $auth->handleCallback($_GET);
$_SESSION['access_token'] = $result['tokens']['access_token'] ?? null; $_SESSION['access_token'] = $result['tokens']['access_token'] ?? null;