Skip to content

Commit 763b6b2

Browse files
Add MusicBrainz Provider (#768)
Co-authored-by: Lucas Michot <lucas@semalead.com>
0 parents  commit 763b6b2

File tree

4 files changed

+210
-0
lines changed

4 files changed

+210
-0
lines changed

KeycloakExtendSocialite.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace SocialiteProviders\Keycloak;
4+
5+
use SocialiteProviders\Manager\SocialiteWasCalled;
6+
7+
class KeycloakExtendSocialite
8+
{
9+
/**
10+
* Register the provider.
11+
*
12+
* @param \SocialiteProviders\Manager\SocialiteWasCalled $socialiteWasCalled
13+
*/
14+
public function handle(SocialiteWasCalled $socialiteWasCalled)
15+
{
16+
$socialiteWasCalled->extendSocialite('keycloak', Provider::class);
17+
}
18+
}

Provider.php

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
<?php
2+
3+
namespace SocialiteProviders\Keycloak;
4+
5+
use GuzzleHttp\RequestOptions;
6+
use Illuminate\Support\Arr;
7+
use SocialiteProviders\Manager\OAuth2\AbstractProvider;
8+
use SocialiteProviders\Manager\OAuth2\User;
9+
10+
class Provider extends AbstractProvider
11+
{
12+
/**
13+
* Unique Provider Identifier.
14+
*/
15+
public const IDENTIFIER = 'KEYCLOAK';
16+
17+
protected $scopeSeparator = ' ';
18+
19+
protected $scopes = ['openid'];
20+
21+
/**
22+
* {@inheritdoc}
23+
*/
24+
public static function additionalConfigKeys()
25+
{
26+
return ['base_url', 'realms'];
27+
}
28+
29+
protected function getBaseUrl()
30+
{
31+
return rtrim(rtrim($this->getConfig('base_url'), '/').'/realms/'.$this->getConfig('realms', 'master'), '/');
32+
}
33+
34+
/**
35+
* {@inheritdoc}
36+
*/
37+
protected function getAuthUrl($state)
38+
{
39+
return $this->buildAuthUrlFromBase($this->getBaseUrl().'/protocol/openid-connect/auth', $state);
40+
}
41+
42+
/**
43+
* {@inheritdoc}
44+
*/
45+
protected function getTokenUrl()
46+
{
47+
return $this->getBaseUrl().'/protocol/openid-connect/token';
48+
}
49+
50+
/**
51+
* {@inheritdoc}
52+
*/
53+
protected function getUserByToken($token)
54+
{
55+
$response = $this->getHttpClient()->get($this->getBaseUrl().'/protocol/openid-connect/userinfo', [
56+
RequestOptions::HEADERS => [
57+
'Authorization' => 'Bearer '.$token,
58+
],
59+
]);
60+
61+
return json_decode((string) $response->getBody(), true);
62+
}
63+
64+
/**
65+
* {@inheritdoc}
66+
*/
67+
protected function mapUserToObject(array $user)
68+
{
69+
return (new User())->setRaw($user)->map([
70+
'id' => Arr::get($user, 'sub'),
71+
'nickname' => Arr::get($user, 'preferred_username'),
72+
'name' => Arr::get($user, 'name'),
73+
'email' => Arr::get($user, 'email'),
74+
]);
75+
}
76+
77+
/**
78+
* {@inheritdoc}
79+
*/
80+
protected function getTokenFields($code)
81+
{
82+
return array_merge(parent::getTokenFields($code), [
83+
'grant_type' => 'authorization_code',
84+
]);
85+
}
86+
87+
/**
88+
* Return logout endpoint with redirect_uri query parameter.
89+
*
90+
* @return string
91+
*/
92+
public function getLogoutUrl(string $redirectUri)
93+
{
94+
return $this->getBaseUrl().'/protocol/openid-connect/logout?redirect_uri='.urlencode($redirectUri);
95+
}
96+
}

README.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Keycloak
2+
3+
```bash
4+
composer require socialiteproviders/keycloak
5+
```
6+
7+
## Installation & Basic Usage
8+
9+
Please see the [Base Installation Guide](https://socialiteproviders.com/usage/), then follow the provider specific instructions below.
10+
11+
### Add configuration to `config/services.php`
12+
13+
```php
14+
'keycloak' => [
15+
'client_id' => env('KEYCLOAK_CLIENT_ID'),
16+
'client_secret' => env('KEYCLOAK_CLIENT_SECRET'),
17+
'redirect' => env('KEYCLOAK_REDIRECT_URI'),
18+
'base_url' => env('KEYCLOAK_BASE_URL'), // Specify your keycloak server URL here
19+
'realms' => env('KEYCLOAK_REALM') // Specify your keycloak realm
20+
],
21+
```
22+
23+
### Add provider event listener
24+
25+
Configure the package's listener to listen for `SocialiteWasCalled` events.
26+
27+
Add the event to your `listen[]` array in `app/Providers/EventServiceProvider`. See the [Base Installation Guide](https://socialiteproviders.com/usage/) for detailed instructions.
28+
29+
```php
30+
protected $listen = [
31+
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
32+
// ... other providers
33+
\SocialiteProviders\Keycloak\KeycloakExtendSocialite::class.'@handle',
34+
],
35+
];
36+
```
37+
38+
### Usage
39+
40+
You should now be able to use the provider like you would regularly use Socialite (assuming you have the facade installed):
41+
42+
```php
43+
return Socialite::driver('keycloak')->redirect();
44+
```
45+
46+
To logout of your app and Keycloak:
47+
```php
48+
public function logout() {
49+
Auth::logout(); // Logout of your app
50+
$redirectUri = Config::get('app.url'); // The URL the user is redirected to
51+
return redirect(Socialite::driver('keycloak')->getLogoutUrl($redirectUri)); // Redirect to Keycloak
52+
}
53+
```
54+
55+
#### Keycloak <= 3.2
56+
57+
Keycloak below v3.2 requires no scopes to be set. Later versions require the `openid` scope for all requests.
58+
59+
```php
60+
return Socialite::driver('keycloak')->scopes([])->redirect();
61+
```
62+
63+
See [the upgrade guide](https://www.keycloak.org/docs/12.0/upgrading/#migrating-to-3-2-0).

composer.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "socialiteproviders/keycloak",
3+
"description": "Keycloak OAuth2 Provider for Laravel Socialite",
4+
"keywords": [
5+
"keycloak",
6+
"laravel",
7+
"oauth",
8+
"provider",
9+
"socialite"
10+
],
11+
"license": "MIT",
12+
"authors": [
13+
{
14+
"name": "Oleg Kuchumov",
15+
"email": "voenniy@gmail.com"
16+
}
17+
],
18+
"require": {
19+
"php": "^7.2 || ^8.0",
20+
"ext-json": "*",
21+
"socialiteproviders/manager": "~4.0"
22+
},
23+
"autoload": {
24+
"psr-4": {
25+
"SocialiteProviders\\Keycloak\\": ""
26+
}
27+
},
28+
"support": {
29+
"issues": "https://github.com/socialiteproviders/providers/issues",
30+
"source": "https://github.com/socialiteproviders/providers",
31+
"docs": "https://socialiteproviders.com/keycloak"
32+
}
33+
}

0 commit comments

Comments
 (0)