Skip to content
Snippets Groups Projects
Unverified Commit d4200bb2 authored by Patrick's avatar Patrick Committed by GitHub
Browse files

Merge pull request #68 from cirrusidentity/52_configurable_well_known

Make OIDC discovery url configurable
parents d36a9a6d 3dab848b
No related branches found
No related tags found
No related merge requests found
......@@ -162,10 +162,16 @@ Not all configuration options from `authoauth2:OAuth2` are supported in `OpenIDC
'clientSecret' => '36aefb235314bad5df075363b79cbbcd',
// Most Optional settings for OAuth2 above can be used
// *** New Optional ***
// *** Optional ***
// Customize post logout redirect, if you don't want to use the standard /module.php/authoauth2/loggedout.php
'postLogoutRedirectUri' => 'https://myapp.example.com/loggedout'
// Set a specific discovery url. Default is $issuer/.well-known/openid-configuration
'discoveryUrl' => 'https://login.microsoftonline.com/common/.well-known/openid-configuration',
// Check if the issuer in the ID token matches the one from discovery. Default true. For some multi-tenant
// applications (for example cross tenant Azure logins) the token issuer varies with tenant
'validateIssuer' => false,
// Earlier version OpenIDConnect authsource doesn't support using `scopes` for overriding scope
//'urlAuthorizeOptions' => [
// 'scope' => 'openid'
......@@ -177,7 +183,7 @@ If your OP supports front channel single logout, you can configure `https://host
## Provider Specific Usage
There are numerous [Offical](http://oauth2-client.thephpleague.com/providers/league/) and [Third-Party](http://oauth2-client.thephpleague.com/providers/thirdparty/) providers
There are numerous [Official](http://oauth2-client.thephpleague.com/providers/league/) and [Third-Party](http://oauth2-client.thephpleague.com/providers/thirdparty/) providers
that you can use instead of the generic OAuth2 provider. Using one of those providers can simplify the configurations.
To use a provider you must first install it `composer require league/oauth2-some-provider`
......
......@@ -16,6 +16,13 @@ $config = array(
*/
],
'templateMicrosoft' => [
'authoauth2:OAuth2',
'template' => 'MicrosoftGraphV1',
'clientId' => 'f579dc6e-58f5-41a8-8bbf-96d54eacfe8d',
'clientSecret' => 'GXc8Q~mgI7kTBllrvpBthUEioeARdjrRYORSyda4',
],
/** Test using Google OIDC but with config explicitly define rather than pulled from .well-know */
'templateGoogle' => [
'authoauth2:OAuth2',
......@@ -38,6 +45,18 @@ $config = array(
*/
],
/** Using the OIDC authsource for MS logins */
'microsoftOIDCSource' => [
'authoauth2:OpenIDConnect',
'issuer' => 'https://sts.windows.net/{tenantid}/',
// When using the 'common' discovery endpoint it allows any Azure user to authenticate, however
// the token issuer is tenant specific and will not match what is in the common discovery document.
'validateIssuer' => false, // issuer is just used to confirm correct discovery endpoint loaded
'discoveryUrl' => 'https://login.microsoftonline.com/common/.well-known/openid-configuration',
'clientId' => 'f579dc6e-58f5-41a8-8bbf-96d54eacfe8d',
'clientSecret' => 'GXc8Q~mgI7kTBllrvpBthUEioeARdjrRYORSyda4',
],
// This is a authentication source which handles admin authentication.
'admin' => array(
......
......@@ -24,6 +24,8 @@ class OpenIDConnectProvider extends AbstractProvider
*/
protected string $issuer;
protected string $discoveryUrl;
/**
* @var ?Configuration
*/
......@@ -39,13 +41,20 @@ class OpenIDConnectProvider extends AbstractProvider
*/
private array $defaultScopes = [];
protected bool $validateIssuer = false;
public function __construct(array $options = [], array $collaborators = [])
{
parent::__construct($options, $collaborators);
$optionsConfig = Configuration::loadFromArray($options);
$this->issuer = $optionsConfig->getString('issuer');
$this->discoveryUrl = $optionsConfig->getOptionalString(
'discoveryUrl',
rtrim($this->issuer, '/') . self::CONFIGURATION_PATH
);
$this->defaultScopes = $optionsConfig->getOptionalArray('scopes', ['openid', 'profile']);
$this->validateIssuer = $optionsConfig->getOptionalBoolean('validateIssuer', true);
}
/**
......@@ -95,8 +104,13 @@ class OpenIDConnectProvider extends AbstractProvider
if (!in_array($this->clientId, $aud)) {
throw new IdentityProviderException("ID token has incorrect audience", 0, $claims->aud);
}
if ($claims->iss !== $this->issuer) {
throw new IdentityProviderException("ID token has incorrect issuer", 0, $claims->iss);
// When working with Azure the issuer is tenant specific, but the discovery metadata can be for all tenants
if ($this->validateIssuer && $claims->iss !== $this->issuer) {
throw new IdentityProviderException(
"ID token has incorrect issuer. Expected '{$this->issuer}' recieved '{$claims->iss}'",
0,
$claims->iss
);
}
} catch (\UnexpectedValueException $e) {
throw new IdentityProviderException("ID token validation failed", 0, $e->getMessage());
......@@ -114,13 +128,18 @@ class OpenIDConnectProvider extends AbstractProvider
return $result;
}
public function getDiscoveryUrl(): string
{
return $this->discoveryUrl;
}
protected function getOpenIDConfiguration(): Configuration
{
if (isset($this->openIdConfiguration)) {
return $this->openIdConfiguration;
}
$req = $this->getRequest('GET', rtrim($this->issuer, '/') . self::CONFIGURATION_PATH);
$req = $this->getRequest('GET', $this->getDiscoveryUrl());
/** @var array $config */
$config = $this->getParsedResponse($req);
$requiredEndPoints = [ "authorization_endpoint", "token_endpoint", "jwks_uri", "issuer", "userinfo_endpoint" ];
......
......@@ -74,4 +74,26 @@ class OpenIDConnectProviderTest extends TestCase
$request = Request::create($url);
$this->assertEquals('openid', $request->query->get('scope'));
}
public function testConfiguringDiscoveryUrl(): void
{
$provider = new OpenIDConnectProvider(
['issuer' => 'https://accounts.example.com']
);
$this->assertEquals(
'https://accounts.example.com/.well-known/openid-configuration',
$provider->getDiscoveryUrl()
);
$provider = new OpenIDConnectProvider(
[
'issuer' => 'https://accounts.example.com',
'discoveryUrl' => 'https://otherhost.example.com/path/path2/.well-known/openid-configuration'
]
);
$this->assertEquals(
'https://otherhost.example.com/path/path2/.well-known/openid-configuration',
$provider->getDiscoveryUrl()
);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment