mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-10-01 01:36:00 -04:00
OIDC: Cleaned up provider settings, added extra validation
- Added endpoint validation to ensure HTTPS as per spec - Added some missing types - Removed redirectUri from OidcProviderSettings since it's not a provider-based setting, but a setting for the oauth client, so extracted that back to service.
This commit is contained in:
parent
dc6013fd7e
commit
d640411adb
@ -18,7 +18,6 @@ class OidcProviderSettings
|
|||||||
public string $issuer;
|
public string $issuer;
|
||||||
public string $clientId;
|
public string $clientId;
|
||||||
public string $clientSecret;
|
public string $clientSecret;
|
||||||
public ?string $redirectUri;
|
|
||||||
public ?string $authorizationEndpoint;
|
public ?string $authorizationEndpoint;
|
||||||
public ?string $tokenEndpoint;
|
public ?string $tokenEndpoint;
|
||||||
public ?string $endSessionEndpoint;
|
public ?string $endSessionEndpoint;
|
||||||
@ -38,7 +37,7 @@ class OidcProviderSettings
|
|||||||
/**
|
/**
|
||||||
* Apply an array of settings to populate setting properties within this class.
|
* Apply an array of settings to populate setting properties within this class.
|
||||||
*/
|
*/
|
||||||
protected function applySettingsFromArray(array $settingsArray)
|
protected function applySettingsFromArray(array $settingsArray): void
|
||||||
{
|
{
|
||||||
foreach ($settingsArray as $key => $value) {
|
foreach ($settingsArray as $key => $value) {
|
||||||
if (property_exists($this, $key)) {
|
if (property_exists($this, $key)) {
|
||||||
@ -52,7 +51,7 @@ class OidcProviderSettings
|
|||||||
*
|
*
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
protected function validateInitial()
|
protected function validateInitial(): void
|
||||||
{
|
{
|
||||||
$required = ['clientId', 'clientSecret', 'redirectUri', 'issuer'];
|
$required = ['clientId', 'clientSecret', 'redirectUri', 'issuer'];
|
||||||
foreach ($required as $prop) {
|
foreach ($required as $prop) {
|
||||||
@ -74,12 +73,20 @@ class OidcProviderSettings
|
|||||||
public function validate(): void
|
public function validate(): void
|
||||||
{
|
{
|
||||||
$this->validateInitial();
|
$this->validateInitial();
|
||||||
|
|
||||||
$required = ['keys', 'tokenEndpoint', 'authorizationEndpoint'];
|
$required = ['keys', 'tokenEndpoint', 'authorizationEndpoint'];
|
||||||
foreach ($required as $prop) {
|
foreach ($required as $prop) {
|
||||||
if (empty($this->$prop)) {
|
if (empty($this->$prop)) {
|
||||||
throw new InvalidArgumentException("Missing required configuration \"{$prop}\" value");
|
throw new InvalidArgumentException("Missing required configuration \"{$prop}\" value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$endpointProperties = ['tokenEndpoint', 'authorizationEndpoint', 'userinfoEndpoint'];
|
||||||
|
foreach ($endpointProperties as $prop) {
|
||||||
|
if (is_string($this->$prop) && !str_starts_with($this->$prop, 'https://')) {
|
||||||
|
throw new InvalidArgumentException("Endpoint value for \"{$prop}\" must start with https://");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -87,7 +94,7 @@ class OidcProviderSettings
|
|||||||
*
|
*
|
||||||
* @throws OidcIssuerDiscoveryException
|
* @throws OidcIssuerDiscoveryException
|
||||||
*/
|
*/
|
||||||
public function discoverFromIssuer(ClientInterface $httpClient, Repository $cache, int $cacheMinutes)
|
public function discoverFromIssuer(ClientInterface $httpClient, Repository $cache, int $cacheMinutes): void
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$cacheKey = 'oidc-discovery::' . $this->issuer;
|
$cacheKey = 'oidc-discovery::' . $this->issuer;
|
||||||
@ -180,9 +187,9 @@ class OidcProviderSettings
|
|||||||
/**
|
/**
|
||||||
* Get the settings needed by an OAuth provider, as a key=>value array.
|
* Get the settings needed by an OAuth provider, as a key=>value array.
|
||||||
*/
|
*/
|
||||||
public function arrayForProvider(): array
|
public function arrayForOAuthProvider(): array
|
||||||
{
|
{
|
||||||
$settingKeys = ['clientId', 'clientSecret', 'redirectUri', 'authorizationEndpoint', 'tokenEndpoint', 'userinfoEndpoint'];
|
$settingKeys = ['clientId', 'clientSecret', 'authorizationEndpoint', 'tokenEndpoint', 'userinfoEndpoint'];
|
||||||
$settings = [];
|
$settings = [];
|
||||||
foreach ($settingKeys as $setting) {
|
foreach ($settingKeys as $setting) {
|
||||||
$settings[$setting] = $this->$setting;
|
$settings[$setting] = $this->$setting;
|
||||||
|
@ -91,7 +91,6 @@ class OidcService
|
|||||||
'issuer' => $config['issuer'],
|
'issuer' => $config['issuer'],
|
||||||
'clientId' => $config['client_id'],
|
'clientId' => $config['client_id'],
|
||||||
'clientSecret' => $config['client_secret'],
|
'clientSecret' => $config['client_secret'],
|
||||||
'redirectUri' => url('/oidc/callback'),
|
|
||||||
'authorizationEndpoint' => $config['authorization_endpoint'],
|
'authorizationEndpoint' => $config['authorization_endpoint'],
|
||||||
'tokenEndpoint' => $config['token_endpoint'],
|
'tokenEndpoint' => $config['token_endpoint'],
|
||||||
'endSessionEndpoint' => is_string($config['end_session_endpoint']) ? $config['end_session_endpoint'] : null,
|
'endSessionEndpoint' => is_string($config['end_session_endpoint']) ? $config['end_session_endpoint'] : null,
|
||||||
@ -130,7 +129,10 @@ class OidcService
|
|||||||
*/
|
*/
|
||||||
protected function getProvider(OidcProviderSettings $settings): OidcOAuthProvider
|
protected function getProvider(OidcProviderSettings $settings): OidcOAuthProvider
|
||||||
{
|
{
|
||||||
$provider = new OidcOAuthProvider($settings->arrayForProvider(), [
|
$provider = new OidcOAuthProvider([
|
||||||
|
...$settings->arrayForOAuthProvider(),
|
||||||
|
'redirectUri' => url('/oidc/callback'),
|
||||||
|
], [
|
||||||
'httpClient' => $this->http->buildClient(5),
|
'httpClient' => $this->http->buildClient(5),
|
||||||
'optionProvider' => new HttpBasicAuthOptionProvider(),
|
'optionProvider' => new HttpBasicAuthOptionProvider(),
|
||||||
]);
|
]);
|
||||||
|
Loading…
Reference in New Issue
Block a user