OIDC: Added PKCE functionality

Related to #4734.
Uses core logic from League AbstractProvider.
This commit is contained in:
Dan Brown 2024-01-25 14:24:46 +00:00
parent 5903823eed
commit 3e9e196cda
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
2 changed files with 23 additions and 20 deletions

View File

@ -83,15 +83,9 @@ class OidcOAuthProvider extends AbstractProvider
/** /**
* Checks a provider response for errors. * Checks a provider response for errors.
*
* @param ResponseInterface $response
* @param array|string $data Parsed response data
*
* @throws IdentityProviderException * @throws IdentityProviderException
*
* @return void
*/ */
protected function checkResponse(ResponseInterface $response, $data) protected function checkResponse(ResponseInterface $response, $data): void
{ {
if ($response->getStatusCode() >= 400 || isset($data['error'])) { if ($response->getStatusCode() >= 400 || isset($data['error'])) {
throw new IdentityProviderException( throw new IdentityProviderException(
@ -105,13 +99,8 @@ class OidcOAuthProvider extends AbstractProvider
/** /**
* Generates a resource owner object from a successful resource owner * Generates a resource owner object from a successful resource owner
* details request. * details request.
*
* @param array $response
* @param AccessToken $token
*
* @return ResourceOwnerInterface
*/ */
protected function createResourceOwner(array $response, AccessToken $token) protected function createResourceOwner(array $response, AccessToken $token): ResourceOwnerInterface
{ {
return new GenericResourceOwner($response, ''); return new GenericResourceOwner($response, '');
} }
@ -121,14 +110,18 @@ class OidcOAuthProvider extends AbstractProvider
* *
* The grant that was used to fetch the response can be used to provide * The grant that was used to fetch the response can be used to provide
* additional context. * additional context.
*
* @param array $response
* @param AbstractGrant $grant
*
* @return OidcAccessToken
*/ */
protected function createAccessToken(array $response, AbstractGrant $grant) protected function createAccessToken(array $response, AbstractGrant $grant): OidcAccessToken
{ {
return new OidcAccessToken($response); return new OidcAccessToken($response);
} }
/**
* Get the method used for PKCE code verifier hashing, which is passed
* in the "code_challenge_method" parameter in the authorization request.
*/
protected function getPkceMethod(): string
{
return static::PKCE_METHOD_S256;
}
} }

View File

@ -33,6 +33,8 @@ class OidcService
/** /**
* Initiate an authorization flow. * Initiate an authorization flow.
* Provides back an authorize redirect URL, in addition to other
* details which may be required for the auth flow.
* *
* @throws OidcException * @throws OidcException
* *
@ -42,8 +44,12 @@ class OidcService
{ {
$settings = $this->getProviderSettings(); $settings = $this->getProviderSettings();
$provider = $this->getProvider($settings); $provider = $this->getProvider($settings);
$url = $provider->getAuthorizationUrl();
session()->put('oidc_pkce_code', $provider->getPkceCode() ?? '');
return [ return [
'url' => $provider->getAuthorizationUrl(), 'url' => $url,
'state' => $provider->getState(), 'state' => $provider->getState(),
]; ];
} }
@ -63,6 +69,10 @@ class OidcService
$settings = $this->getProviderSettings(); $settings = $this->getProviderSettings();
$provider = $this->getProvider($settings); $provider = $this->getProvider($settings);
// Set PKCE code flashed at login
$pkceCode = session()->pull('oidc_pkce_code', '');
$provider->setPkceCode($pkceCode);
// Try to exchange authorization code for access token // Try to exchange authorization code for access token
$accessToken = $provider->getAccessToken('authorization_code', [ $accessToken = $provider->getAccessToken('authorization_code', [
'code' => $authorizationCode, 'code' => $authorizationCode,