From 8ce696dff62afc9a366f95231fe03a25078b4ce1 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sun, 10 Oct 2021 19:14:08 +0100 Subject: [PATCH] Started on a custom oidc oauth provider --- .../Access/OpenIdConnectOAuthProvider.php | 109 ++++++++++++++++++ app/Auth/Access/OpenIdConnectService.php | 31 +++-- 2 files changed, 124 insertions(+), 16 deletions(-) create mode 100644 app/Auth/Access/OpenIdConnectOAuthProvider.php diff --git a/app/Auth/Access/OpenIdConnectOAuthProvider.php b/app/Auth/Access/OpenIdConnectOAuthProvider.php new file mode 100644 index 000000000..60ae2aa09 --- /dev/null +++ b/app/Auth/Access/OpenIdConnectOAuthProvider.php @@ -0,0 +1,109 @@ +authorizationEndpoint; + } + + /** + * Returns the base URL for requesting an access token. + */ + public function getBaseAccessTokenUrl(array $params): string + { + return $this->tokenEndpoint; + } + + /** + * Returns the URL for requesting the resource owner's details. + */ + public function getResourceOwnerDetailsUrl(AccessToken $token): string + { + return ''; + } + + /** + * Returns the default scopes used by this provider. + * + * This should only be the scopes that are required to request the details + * of the resource owner, rather than all the available scopes. + */ + protected function getDefaultScopes(): array + { + return ['openid', 'profile', 'email']; + } + + + /** + * Returns the string that should be used to separate scopes when building + * the URL for requesting an access token. + */ + protected function getScopeSeparator(): string + { + return ' '; + } + + /** + * Checks a provider response for errors. + * + * @param ResponseInterface $response + * @param array|string $data Parsed response data + * @return void + * @throws IdentityProviderException + */ + protected function checkResponse(ResponseInterface $response, $data) + { + if ($response->getStatusCode() >= 400 || isset($data['error'])) { + throw new IdentityProviderException( + $data['error'] ?? $response->getReasonPhrase(), + $response->getStatusCode(), + (string) $response->getBody() + ); + } + } + + /** + * Generates a resource owner object from a successful resource owner + * details request. + * + * @param array $response + * @param AccessToken $token + * @return ResourceOwnerInterface + */ + protected function createResourceOwner(array $response, AccessToken $token) + { + return new GenericResourceOwner($response, ''); + } +} \ No newline at end of file diff --git a/app/Auth/Access/OpenIdConnectService.php b/app/Auth/Access/OpenIdConnectService.php index 2548aee6e..01050b5e5 100644 --- a/app/Auth/Access/OpenIdConnectService.php +++ b/app/Auth/Access/OpenIdConnectService.php @@ -6,10 +6,8 @@ use BookStack\Exceptions\OpenIdConnectException; use BookStack\Exceptions\StoppedAuthenticationException; use BookStack\Exceptions\UserRegistrationException; use Exception; -use Lcobucci\JWT\Signer\Rsa\Sha256; use Lcobucci\JWT\Token; -use OpenIDConnectClient\AccessToken; -use OpenIDConnectClient\OpenIDConnectProvider; +use League\OAuth2\Client\Token\AccessToken; /** * Class OpenIdConnectService @@ -66,27 +64,18 @@ class OpenIdConnectService /** * Load the underlying OpenID Connect Provider. */ - protected function getProvider(): OpenIDConnectProvider + protected function getProvider(): OpenIdConnectOAuthProvider { // Setup settings $settings = [ 'clientId' => $this->config['client_id'], 'clientSecret' => $this->config['client_secret'], - 'idTokenIssuer' => $this->config['issuer'], 'redirectUri' => url('/oidc/redirect'), - 'urlAuthorize' => $this->config['authorization_endpoint'], - 'urlAccessToken' => $this->config['token_endpoint'], - 'urlResourceOwnerDetails' => null, - 'publicKey' => $this->config['jwt_public_key'], - 'scopes' => 'profile email', + 'authorizationEndpoint' => $this->config['authorization_endpoint'], + 'tokenEndpoint' => $this->config['token_endpoint'], ]; - // Setup services - $services = [ - 'signer' => new Sha256(), - ]; - - return new OpenIDConnectProvider($settings, $services); + return new OpenIdConnectOAuthProvider($settings); } /** @@ -135,6 +124,16 @@ class OpenIdConnectService */ protected function processAccessTokenCallback(AccessToken $accessToken): User { + dd($accessToken->getValues()); + // TODO - Create a class to manage token parsing and validation on this + // Using the config params: + // $this->config['jwt_public_key'] + // $this->config['issuer'] + // + // Ensure ID token validation is done: + // https://openid.net/specs/openid-connect-basic-1_0.html#IDTokenValidation + // To full affect and tested + $userDetails = $this->getUserDetails($accessToken->getIdToken()); $isLoggedIn = auth()->check();