--- /dev/null
+<?php
+
+namespace BookStack\Auth\Access;
+
+use League\OAuth2\Client\Provider\AbstractProvider;
+use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
+use League\OAuth2\Client\Provider\GenericResourceOwner;
+use League\OAuth2\Client\Provider\ResourceOwnerInterface;
+use League\OAuth2\Client\Token\AccessToken;
+use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * Extended OAuth2Provider for using with OIDC.
+ * Credit to the https://github.com/steverhoades/oauth2-openid-connect-client
+ * project for the idea of extending a League\OAuth2 client for this use-case.
+ */
+class OpenIdConnectOAuthProvider extends AbstractProvider
+{
+ use BearerAuthorizationTrait;
+
+ /**
+ * @var string
+ */
+ protected $authorizationEndpoint;
+
+ /**
+ * @var string
+ */
+ protected $tokenEndpoint;
+
+
+ /**
+ * Returns the base URL for authorizing a client.
+ */
+ public function getBaseAuthorizationUrl(): string
+ {
+ return $this->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
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
/**
* 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);
}
/**
*/
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();