mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-04-26 14:14:05 +08:00
Started on a custom oidc oauth provider
This commit is contained in:
parent
41438adbd1
commit
8ce696dff6
109
app/Auth/Access/OpenIdConnectOAuthProvider.php
Normal file
109
app/Auth/Access/OpenIdConnectOAuthProvider.php
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<?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, '');
|
||||||
|
}
|
||||||
|
}
|
@ -6,10 +6,8 @@ use BookStack\Exceptions\OpenIdConnectException;
|
|||||||
use BookStack\Exceptions\StoppedAuthenticationException;
|
use BookStack\Exceptions\StoppedAuthenticationException;
|
||||||
use BookStack\Exceptions\UserRegistrationException;
|
use BookStack\Exceptions\UserRegistrationException;
|
||||||
use Exception;
|
use Exception;
|
||||||
use Lcobucci\JWT\Signer\Rsa\Sha256;
|
|
||||||
use Lcobucci\JWT\Token;
|
use Lcobucci\JWT\Token;
|
||||||
use OpenIDConnectClient\AccessToken;
|
use League\OAuth2\Client\Token\AccessToken;
|
||||||
use OpenIDConnectClient\OpenIDConnectProvider;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class OpenIdConnectService
|
* Class OpenIdConnectService
|
||||||
@ -66,27 +64,18 @@ class OpenIdConnectService
|
|||||||
/**
|
/**
|
||||||
* Load the underlying OpenID Connect Provider.
|
* Load the underlying OpenID Connect Provider.
|
||||||
*/
|
*/
|
||||||
protected function getProvider(): OpenIDConnectProvider
|
protected function getProvider(): OpenIdConnectOAuthProvider
|
||||||
{
|
{
|
||||||
// Setup settings
|
// Setup settings
|
||||||
$settings = [
|
$settings = [
|
||||||
'clientId' => $this->config['client_id'],
|
'clientId' => $this->config['client_id'],
|
||||||
'clientSecret' => $this->config['client_secret'],
|
'clientSecret' => $this->config['client_secret'],
|
||||||
'idTokenIssuer' => $this->config['issuer'],
|
|
||||||
'redirectUri' => url('/oidc/redirect'),
|
'redirectUri' => url('/oidc/redirect'),
|
||||||
'urlAuthorize' => $this->config['authorization_endpoint'],
|
'authorizationEndpoint' => $this->config['authorization_endpoint'],
|
||||||
'urlAccessToken' => $this->config['token_endpoint'],
|
'tokenEndpoint' => $this->config['token_endpoint'],
|
||||||
'urlResourceOwnerDetails' => null,
|
|
||||||
'publicKey' => $this->config['jwt_public_key'],
|
|
||||||
'scopes' => 'profile email',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
// Setup services
|
return new OpenIdConnectOAuthProvider($settings);
|
||||||
$services = [
|
|
||||||
'signer' => new Sha256(),
|
|
||||||
];
|
|
||||||
|
|
||||||
return new OpenIDConnectProvider($settings, $services);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -135,6 +124,16 @@ class OpenIdConnectService
|
|||||||
*/
|
*/
|
||||||
protected function processAccessTokenCallback(AccessToken $accessToken): User
|
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());
|
$userDetails = $this->getUserDetails($accessToken->getIdToken());
|
||||||
$isLoggedIn = auth()->check();
|
$isLoggedIn = auth()->check();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user