Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save mehrdad-shokri/c2f4a1a7b37bafc99e2e35c33288f6e5 to your computer and use it in GitHub Desktop.
Save mehrdad-shokri/c2f4a1a7b37bafc99e2e35c33288f6e5 to your computer and use it in GitHub Desktop.
A way to use Keycloak as provider for login into laravel
This gist is created because the library i use eloquent-oauth-l5 has a pull-request (custom providers feature ) awaiting a merge
So here my way to use this feature and use keycloak as custom provider.
Inside composer.json
"repositories": [
{
"type": "vcs",
"url": "https://github.com/tysonlt/eloquent-oauth-l5"
}
],
"require": {
"php": ">=5.5.9",
"laravel/framework": "5.2.*",
"adamwathan/eloquent-oauth-l5": "dev-master"
},
Launch composer update ( takes time to execute )
Make all the steps required on the eloquent-oauth-5 readme ( section custom provider )
Configure the eloquent-oauth.php
'custom-providers' => [
'keycloak' => [
'client_id' => 'xxxxxxx',
'client_secret' => 'xxxxxxxx',
'redirect_uri' => 'http://localhost.dev/keycloak/callback',
'scope' => [],
'provider_class' => App\Providers\OAuth2\KeycloakProvider::class
],
],
Create the App\Providers\OAuth2\KeycloakProvider.php
replace keycloak.server by your current keycloak server instance url
and REPLACEBYREALM by the name of your realm
<?php
namespace App\Providers\OAuth2;
use SocialNorm\Exceptions\InvalidAuthorizationCodeException;
use SocialNorm\Providers\OAuth2Provider;
class KeycloakProvider extends OAuth2Provider
{
protected $authorizeUrl = "http://keycloak.server/auth/realms/REPLACEBYREALM/protocol/openid-connect/auth";
protected $accessTokenUrl = "http://keycloak.server/auth/realms/REPLACEBYREALM/protocol/openid-connect/token";
protected $userDataUrl = "http://keycloak.server/auth/realms/REPLACEBYREALM/protocol/openid-connect/userinfo";
protected $scope = [
'view-profile',
'manage-account',
];
protected $headers = [
'authorize' => [],
'access_token' => [
'Content-Type' => 'application/x-www-form-urlencoded'
],
'user_details' => [],
];
protected function compileScopes()
{
return implode(' ', $this->scope);
}
protected function getAuthorizeUrl()
{
return $this->authorizeUrl;
}
protected function getAccessTokenBaseUrl()
{
return $this->accessTokenUrl;
}
protected function getUserDataUrl()
{
return $this->userDataUrl;
}
protected function parseTokenResponse($response)
{
return $this->parseJsonTokenResponse($response);
}
protected function requestUserData()
{
$url = $this->buildUserDataUrl();
$response = $this->httpClient->get($url, [
'headers' => [
'Authorization' => 'Bearer ' . $this->accessToken
]
]);
return $this->parseUserDataResponse((string)$response->getBody());
}
protected function parseUserDataResponse($response)
{
return json_decode($response, true);
}
protected function userId()
{
return $this->getProviderUserData('sub');
}
protected function nickname()
{
return $this->getProviderUserData('preferred_username');
}
protected function fullName()
{
return $this->getProviderUserData('given_name') . ' ' . $this->getProviderUserData('family_name');
}
protected function avatar()
{
return "";
}
protected function email()
{
return $this->getProviderUserData('email');
}
}
Then Configure your routes
Route::get('keycloak/authorize', function ($provider) {
return SocialAuth::authorize('keycloak');
});
//OAuth redirects here after authorization
Route::get('keycloak/callback', function () {
// Automatically log in existing users
// or create a new user if necessary.
SocialAuth::login('keycloak', function ($user, $details) {
$user->name = $details->nickname;
$user->email = $details->email;
$user->save();
});
return Redirect::intended();
});
Route::get('keycloak/logout', function () {
Auth::logout();
$logout_url = "http://keycloak.server/auth/realms/irispass/REPLACEBYREALM/openid-connect/logout?redirect_uri=HOME_PAGE_URL_ENCODED_URI";
return redirect($logout_url);
});
After this you can add theses links for testing inside the welcome.blade
<a href="keycloak/authorize" class="button">
<span>login</span>
</a>
<a href="keycloak/logout" class="button">
<span>logout</span>
</a>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment