Skip to content

Instantly share code, notes, and snippets.

@nmfzone
Last active February 4, 2020 11:53
Show Gist options
  • Save nmfzone/143fefd0ca27c11a63eaf2de9e6dfb0a to your computer and use it in GitHub Desktop.
Save nmfzone/143fefd0ca27c11a63eaf2de9e6dfb0a to your computer and use it in GitHub Desktop.
Example Implementation SSO, CAS like, and SLO in Laravel. Custom Auth Guards for SSO.
<?php
class GatewayGuard implements Guard
{
/**
* Retrieve the access token if exists.
*
* @return string|null
*/
protected function retrieveAccessToken()
{
$ssoUser = $this->request->cookie('sso_user');
$accessToken = null;
if ($ssoUser) {
$http = new Client();
try {
// Get access token (machine-to-machine access token).
$guzzleResponse = $http->post(config('services.gateway.sso_token_url'), [
'form_params' => [
'client_id' => config('services.gateway.sso_client_id'),
'client_secret' => config('services.gateway.sso_client_secret'),
'grant_type' => 'client_credentials',
],
'timeout' => 15,
]);
$clientCredential = json_decode($guzzleResponse->getBody());
// Get access token for the sso user.
$guzzleResponse = $http->post(config('services.gateway.sso_cas_url'), [
'form_params' => [
'sso_user' => $ssoUser,
],
'headers' => [
'Authorization' => 'Bearer ' . $clientCredential->access_token,
],
'timeout' => 15,
]);
$personalAccess = json_decode($guzzleResponse->getBody());
$accessToken = $personalAccess->access_token;
} catch (BadResponseException $e) {
//
}
}
return $accessToken;
}
/**
* Retrieve the user from connect api.
*
* @param string $accessToken
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
protected function retrieveUserFromApi($accessToken)
{
$http = new Client();
$user = null;
try {
$guzzleResponse = $http->get(config('services.gateway.current_user_url'), [
'headers' => [
'Authorization' => 'Bearer ' . $accessToken,
],
'timeout' => 15,
]);
$response = json_decode($guzzleResponse->getBody(), true);
$user = new User($response['data']);
$user->setAccessToken($accessToken);
} catch (BadResponseException $e) {
//
}
return $user;
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
if ($this->loggedOut) {
return;
}
if (! is_null($this->user)) {
return $this->user;
}
$ssoUser = $this->request->cookie('sso_user');
$accessToken = $this->session->get($this->getName());
// If the sso_user is null, it means user logged out from the gateway.
// Then, we should destroy session in this application.
if (is_null($ssoUser)) {
$this->user = null;
$this->clearUserDataFromStorage();
return $this->user;
}
if (! is_null($accessToken) && $this->user = $this->retrieveUserFromApi($accessToken)) {
$this->fireAuthenticatedEvent($this->user);
}
if (is_null($this->user)) {
$accessToken = $this->retrieveAccessToken();
$this->user = $this->retrieveUserFromApi($accessToken);
if ($this->user) {
$this->updateSession($accessToken);
$this->fireLoginEvent($this->user);
}
}
return $this->user;
}
/**
* Remove the user data from the session.
*
* @return void
*/
protected function clearUserDataFromStorage()
{
$this->session->remove($this->getName());
Cookie::queue(Cookie::forget('sso_user'));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment