fix(auth): block OIDC token exchange without PKCE verifier
Throw a session-expired error when the PKCE verifier is missing and keep the settings component mount redirect-compatible.
This commit is contained in:
parent
c656892738
commit
a1dbde3412
3 changed files with 11 additions and 10 deletions
|
|
@ -209,9 +209,11 @@ public function getAccessTokenResponse($code)
|
|||
$fields = $this->getTokenFields($code);
|
||||
if ($this->getConfig()->usePkce) {
|
||||
$verifier = $this->pullOidcFlowValue($this->verifierSessionKey((string) $this->request->input('state')));
|
||||
if ($verifier !== null) {
|
||||
$fields['code_verifier'] = $verifier;
|
||||
if ($verifier === null) {
|
||||
throw new OidcException('OIDC login session expired. Please try again.');
|
||||
}
|
||||
|
||||
$fields['code_verifier'] = $verifier;
|
||||
}
|
||||
|
||||
$response = $this->getHttpClient()->post($this->getTokenUrl(), [
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
use App\Models\InstanceSettings;
|
||||
use App\Models\OauthSetting;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Livewire\Component;
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ private function validationRules(?string $provider = null): array
|
|||
return $rules;
|
||||
}
|
||||
|
||||
public function mount(?string $provider = null)
|
||||
public function mount(?string $provider = null): ?RedirectResponse
|
||||
{
|
||||
if (! isInstanceAdmin()) {
|
||||
return redirect()->route('home');
|
||||
|
|
@ -73,6 +74,8 @@ public function mount(?string $provider = null)
|
|||
if ($this->selectedProvider !== null && ! array_key_exists($this->selectedProvider, $this->oauth_settings_map)) {
|
||||
abort(404);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function updateOauthSettings(?string $provider = null): void
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
<?php
|
||||
|
||||
use App\Auth\Oidc\Exceptions\OidcException;
|
||||
use App\Auth\Oidc\OidcConfig;
|
||||
use App\Auth\Oidc\OidcDiscoveryDocument;
|
||||
use App\Auth\Oidc\OidcDiscoveryService;
|
||||
|
|
@ -128,7 +129,7 @@ function oidc_provider(Request $request): TestOidcProviderWithExposedAuthUrl
|
|||
->and($session->has('oidc.code_verifier.state-value'))->toBeFalse();
|
||||
});
|
||||
|
||||
it('does not send an expired oidc pkce verifier during token exchange', function () {
|
||||
it('throws a session expired error for an expired oidc pkce verifier during token exchange', function () {
|
||||
$session = oidc_provider_session();
|
||||
$session->put('oidc.code_verifier.state-value', [
|
||||
'value' => 'expired-verifier',
|
||||
|
|
@ -144,9 +145,4 @@ function oidc_provider(Request $request): TestOidcProviderWithExposedAuthUrl
|
|||
$provider->setHttpClient(new Client(['handler' => $handler]));
|
||||
|
||||
$provider->getAccessTokenResponse('authorization-code');
|
||||
|
||||
parse_str((string) $history[0]['request']->getBody(), $tokenRequestFields);
|
||||
|
||||
expect($tokenRequestFields)->not->toHaveKey('code_verifier')
|
||||
->and($session->has('oidc.code_verifier.state-value'))->toBeFalse();
|
||||
});
|
||||
})->throws(OidcException::class, 'OIDC login session expired. Please try again.');
|
||||
|
|
|
|||
Loading…
Reference in a new issue