-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOpenIDConnectServiceProvider.php
More file actions
100 lines (84 loc) · 3.4 KB
/
Copy pathOpenIDConnectServiceProvider.php
File metadata and controls
100 lines (84 loc) · 3.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
<?php
namespace SocialiteProviders\OpenIDConnect;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\ServiceProvider;
use InvalidArgumentException;
use SocialiteProviders\Manager\SocialiteWasCalled;
use SocialiteProviders\OpenIDConnect\Providers\Auth0Provider;
use SocialiteProviders\OpenIDConnect\Providers\EntraProvider;
use SocialiteProviders\OpenIDConnect\Providers\GoogleProvider;
use SocialiteProviders\OpenIDConnect\Providers\KeycloakProvider;
use SocialiteProviders\OpenIDConnect\Providers\OktaProvider;
/**
* Registers each config/oidc.php connection as its own Socialite driver
* named "{prefix}{connection}", mirroring its config into services.* where
* the manager's ConfigRetriever looks it up. A plain services.openidconnect
* block remains as a single-connection fallback.
*/
class OpenIDConnectServiceProvider extends ServiceProvider
{
/** @var array<string, class-string<Provider>> */
protected const PROVIDERS = [
'entra' => EntraProvider::class,
'keycloak' => KeycloakProvider::class,
'auth0' => Auth0Provider::class,
'okta' => OktaProvider::class,
'google' => GoogleProvider::class,
];
public function register(): void
{
$this->mergeConfigFrom(__DIR__.'/config/oidc.php', 'oidc');
}
public function boot(): void
{
if ($this->app->runningInConsole()) {
$this->publishes([
__DIR__.'/config/oidc.php' => $this->app->configPath('oidc.php'),
], 'oidc-config');
}
foreach ($this->connections() as $driver => [$connection, $providerClass]) {
config(['services.'.$driver => $connection]);
}
Event::listen(SocialiteWasCalled::class, function (SocialiteWasCalled $event) {
foreach ($this->connections() as $driver => [$connection, $providerClass]) {
$event->extendSocialite($driver, $providerClass);
}
if (($services = config('services.openidconnect')) !== null) {
$event->extendSocialite('openidconnect', $this->resolveProviderClass(
$services['provider'] ?? Provider::class,
'openidconnect',
));
}
});
}
/**
* @return array<string, array{0: array, 1: class-string<Provider>}>
*/
protected function connections(): array
{
$prefix = (string) config('oidc.driver_prefix', 'oidc_');
$connections = [];
foreach ((array) config('oidc.connections', []) as $name => $connection) {
if (! is_array($connection)) {
continue;
}
$providerClass = $this->resolveProviderClass($connection['provider'] ?? Provider::class, $name);
$connections[$prefix.$name] = [$connection, $providerClass];
}
return $connections;
}
/**
* @return class-string<Provider>
*/
protected function resolveProviderClass(string $provider, string $connection): string
{
$class = static::PROVIDERS[strtolower($provider)] ?? $provider;
if (! is_a($class, Provider::class, true)) {
throw new InvalidArgumentException(
'OIDC: connection ['.$connection.'] provider ['.$provider.'] must be one of ['
.implode(', ', array_keys(static::PROVIDERS)).'] or a class extending '.Provider::class.'.'
);
}
return $class;
}
}