Last active
February 4, 2020 11:53
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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