docs: add OIDC nonce guidance and callback error handling
This commit is contained in:
@@ -77,7 +77,12 @@ $config = Config::fromArray([
|
|||||||
$client = new AuthClient($config);
|
$client = new AuthClient($config);
|
||||||
|
|
||||||
// Step 1: redirect user to provider
|
// Step 1: redirect user to provider
|
||||||
$auth = $client->buildAuthorisationUrl();
|
$auth = $client->buildAuthorisationUrl([
|
||||||
|
'extra' => [
|
||||||
|
// Some providers require nonce for OIDC requests.
|
||||||
|
'nonce' => rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '='),
|
||||||
|
],
|
||||||
|
]);
|
||||||
header('Location: ' . $auth['url']);
|
header('Location: ' . $auth['url']);
|
||||||
exit;
|
exit;
|
||||||
```
|
```
|
||||||
@@ -123,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.
|
||||||
|
- 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.
|
||||||
- Keep access tokens out of logs and browser-visible output.
|
- Keep access tokens out of logs and browser-visible output.
|
||||||
|
|||||||
@@ -25,7 +25,15 @@ $client = new AuthClient(Config::fromArray([
|
|||||||
]));
|
]));
|
||||||
|
|
||||||
if (!isset($_SESSION['user'])) {
|
if (!isset($_SESSION['user'])) {
|
||||||
$auth = $client->buildAuthorisationUrl();
|
$auth = $client->buildAuthorisationUrl([
|
||||||
|
'extra' => [
|
||||||
|
// Some providers require nonce for OIDC requests.
|
||||||
|
'nonce' => rtrim(strtr(base64_encode(random_bytes(32)), '+/', '-_'), '='),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
// Prevent stale redirects from being reused from cache.
|
||||||
|
header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
|
||||||
|
header('Pragma: no-cache');
|
||||||
header('Location: ' . $auth['url']);
|
header('Location: ' . $auth['url']);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
@@ -54,6 +62,12 @@ $client = new AuthClient(Config::fromArray([
|
|||||||
'redirectUri' => 'https://your-app.example/callback.php',
|
'redirectUri' => 'https://your-app.example/callback.php',
|
||||||
]));
|
]));
|
||||||
|
|
||||||
|
if (isset($_GET['error'])) {
|
||||||
|
$description = isset($_GET['error_description']) ? (string) $_GET['error_description'] : 'Unknown provider error';
|
||||||
|
http_response_code(400);
|
||||||
|
exit('Authorization failed: ' . $description);
|
||||||
|
}
|
||||||
|
|
||||||
$result = $client->handleCallback($_GET);
|
$result = $client->handleCallback($_GET);
|
||||||
|
|
||||||
$_SESSION['user'] = [
|
$_SESSION['user'] = [
|
||||||
@@ -122,6 +136,7 @@ try {
|
|||||||
- Keep provider URLs in environment variables, not hard-coded.
|
- Keep provider URLs in environment variables, not hard-coded.
|
||||||
- Avoid printing tokens in production pages.
|
- Avoid printing tokens in production pages.
|
||||||
- Rotate client secrets for confidential clients.
|
- Rotate client secrets for confidential clients.
|
||||||
|
- Add a unique `nonce` to each OIDC authorisation request.
|
||||||
- Validate `state` on every callback request.
|
- Validate `state` on every callback request.
|
||||||
- Use secure session cookies (`Secure`, `HttpOnly`, `SameSite=Lax` or stricter).
|
- Use secure session cookies (`Secure`, `HttpOnly`, `SameSite=Lax` or stricter).
|
||||||
- HTTPS URLs are enforced by default in `Config::fromArray()`.
|
- HTTPS URLs are enforced by default in `Config::fromArray()`.
|
||||||
|
|||||||
Reference in New Issue
Block a user