- Added `CustomAuthCodeRepository` to cache and store nonces during authorization. - Introduced `CustomTokenResponseType` to resolve cached nonces during token exchange. - Created `oidc-server.php` configuration for OpenID Connect support, including scopes, claims, and token lifetimes. - Registered custom implementations in `AppServiceProvider` with bindings for `AuthCodeRepository` and `TokenResponseType`. - Added feature tests to validate nonce caching and resolution logic.
50 lines
1.4 KiB
PHP
50 lines
1.4 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\OAuth;
|
|
|
|
use Admin9\OidcServer\Services\TokenResponseType as BaseTokenResponseType;
|
|
use Defuse\Crypto\Crypto;
|
|
use Illuminate\Support\Facades\{Cache, Log};
|
|
use Laravel\Passport\Passport;
|
|
use Throwable;
|
|
|
|
class CustomTokenResponseType extends BaseTokenResponseType
|
|
{
|
|
/**
|
|
* Resolve the nonce from the current request or cached authorization code.
|
|
*/
|
|
protected function resolveNonce(): ?string
|
|
{
|
|
// Check if the nonce is directly in the request (e.g. client sent it)
|
|
if ($nonce = request()->input('nonce')) {
|
|
return $nonce;
|
|
}
|
|
|
|
// Otherwise, extract the nonce associated with the authorization code
|
|
$encryptedAuthCode = request()->input('code');
|
|
if (! $encryptedAuthCode) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
$key = Passport::tokenEncryptionKey(app('encrypter'));
|
|
$decrypted = Crypto::decryptWithPassword($encryptedAuthCode, $key);
|
|
$payload = json_decode($decrypted, true);
|
|
|
|
if (isset($payload['auth_code_id'])) {
|
|
$cacheKey = 'oidc_nonce_'.$payload['auth_code_id'];
|
|
$nonce = Cache::get($cacheKey);
|
|
Cache::forget($cacheKey);
|
|
|
|
return $nonce;
|
|
}
|
|
} catch (Throwable $e) {
|
|
Log::error($e->getMessage());
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|