Skip to content
Snippets Groups Projects
Commit 3dab848b authored by Patrick Radtke's avatar Patrick Radtke
Browse files

Make OIDC discovery url configurable

Add docker test case for Microsoft Azure OIDC
parent d36a9a6d
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