Skip to content
Snippets Groups Projects
Commit 358ff07d authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Implemented implicit grant flow (tested with Guacamole auth)

parent f7611ccc
No related branches found
No related tags found
No related merge requests found
...@@ -12,16 +12,16 @@ class IdTokenBuilder { ...@@ -12,16 +12,16 @@ class IdTokenBuilder {
$this->locator = $locator; $this->locator = $locator;
} }
public function getIdToken(AccessToken $accessToken): string { public function getIdToken(AccessToken $accessToken, $nonce = null): string {
$keyPair = $this->locator->getJWKSDAO()->getNewestKeyPair(); $keyPair = $this->locator->getJWKSDAO()->getNewestKeyPair();
$payload = $this->createPayloadArray($accessToken); $payload = $this->createPayloadArray($accessToken, $nonce);
return JWT::encode($payload, $keyPair->privateKey, $keyPair->alg, $keyPair->keyId); return JWT::encode($payload, $keyPair->privateKey, $keyPair->alg, $keyPair->keyId);
} }
private function createPayloadArray(AccessToken $accessToken) { private function createPayloadArray(AccessToken $accessToken, $nonce = null) {
$user = $this->locator->getUserDAO()->findUserById($accessToken->userId); $user = $this->locator->getUserDAO()->findUserById($accessToken->userId);
...@@ -30,9 +30,14 @@ class IdTokenBuilder { ...@@ -30,9 +30,14 @@ class IdTokenBuilder {
'sub' => $user->id, 'sub' => $user->id,
'iat' => time(), 'iat' => time(),
'exp' => time() + 3600, 'exp' => time() + 3600,
'name' => $user->getCompleteName() 'name' => $user->getCompleteName(),
'aud' => $accessToken->clientId
); );
if ($nonce !== null) {
$payloadArr['nonce'] = $nonce;
}
if (in_array("email", $accessToken->scope)) { if (in_array("email", $accessToken->scope)) {
$payloadArr['email'] = $user->getPrimaryEmail(); $payloadArr['email'] = $user->getPrimaryEmail();
} }
......
...@@ -21,7 +21,8 @@ class JWKSHandler { ...@@ -21,7 +21,8 @@ class JWKSHandler {
$rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_PKCS1); $rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_PKCS1);
$rsa->setPublicKeyFormat(RSA::PUBLIC_FORMAT_PKCS8); $rsa->setPublicKeyFormat(RSA::PUBLIC_FORMAT_PKCS8);
$result = $rsa->createKey(); // Guacamole needs a key of at least 2048
$result = $rsa->createKey(2048);
$keyPair = new RSAKeyPair(); $keyPair = new RSAKeyPair();
$keyPair->alg = 'RS256'; $keyPair->alg = 'RS256';
......
...@@ -36,8 +36,10 @@ class OAuth2RequestHandler { ...@@ -36,8 +36,10 @@ class OAuth2RequestHandler {
} }
$state = $params['state']; $state = $params['state'];
if ($state === null) { $nonce = $params['nonce'];
throw new BadRequestException("State is required");
if ($state === null && $nonce === null) {
throw new BadRequestException("State or nonce is required");
} }
// Storing OAuth2 data in session // Storing OAuth2 data in session
...@@ -45,6 +47,7 @@ class OAuth2RequestHandler { ...@@ -45,6 +47,7 @@ class OAuth2RequestHandler {
$oauth2Data->clientId = $client->client; $oauth2Data->clientId = $client->client;
$oauth2Data->redirectUrl = $client->redirectUrl; $oauth2Data->redirectUrl = $client->redirectUrl;
$oauth2Data->state = $state; $oauth2Data->state = $state;
$oauth2Data->nonce = $nonce;
$scope = $params['scope']; $scope = $params['scope'];
if ($scope !== null) { if ($scope !== null) {
...@@ -55,7 +58,7 @@ class OAuth2RequestHandler { ...@@ -55,7 +58,7 @@ class OAuth2RequestHandler {
$session->setOAuth2Data($oauth2Data); $session->setOAuth2Data($oauth2Data);
} }
public function getCodeResponseUrl(): string { public function getRedirectResponseUrl(): string {
$session = $this->locator->getSession(); $session = $this->locator->getSession();
...@@ -70,9 +73,17 @@ class OAuth2RequestHandler { ...@@ -70,9 +73,17 @@ class OAuth2RequestHandler {
$this->locator->getAccessTokenDAO()->createAccessToken($accessToken); $this->locator->getAccessTokenDAO()->createAccessToken($accessToken);
$state = $session->getOAuth2Data()->state; $state = $session->getOAuth2Data()->state;
$nonce = $session->getOAuth2Data()->nonce;
if ($state !== null) {
// Authorization code grant flow
$redirectUrl = $session->getOAuth2Data()->redirectUrl $redirectUrl = $session->getOAuth2Data()->redirectUrl
. '?code=' . $accessToken->code . '&scope=profile&state=' . $state; . '?code=' . $accessToken->code . '&scope=profile&state=' . $state;
} else {
// Implicit grant flow
$idToken = $this->locator->getIdTokenBuilder()->getIdToken($accessToken, $nonce);
$redirectUrl = $session->getOAuth2Data()->redirectUrl . "#id_token=" . $idToken;
}
return $redirectUrl; return $redirectUrl;
} }
......
...@@ -75,7 +75,7 @@ class LoginHandler { ...@@ -75,7 +75,7 @@ class LoginHandler {
if ($session->getOAuth2Data() !== null) { if ($session->getOAuth2Data() !== null) {
$session->setUser($user); $session->setUser($user);
$redirectUrl = $this->locator->getOAuth2RequestHandler()->getCodeResponseUrl(); $redirectUrl = $this->locator->getOAuth2RequestHandler()->getRedirectResponseUrl();
session_destroy(); session_destroy();
return $redirectUrl; return $redirectUrl;
} }
......
...@@ -8,5 +8,6 @@ class OAuth2Data { ...@@ -8,5 +8,6 @@ class OAuth2Data {
public $redirectUrl; public $redirectUrl;
public $state; public $state;
public $scope; public $scope;
public $nonce;
} }
...@@ -79,7 +79,8 @@ Flight::route('GET /auth/oauth2/authorize', function() { ...@@ -79,7 +79,8 @@ Flight::route('GET /auth/oauth2/authorize', function() {
"redirect_uri" => filter_input(INPUT_GET, 'redirect_uri', FILTER_SANITIZE_STRING), "redirect_uri" => filter_input(INPUT_GET, 'redirect_uri', FILTER_SANITIZE_STRING),
"alg" => filter_input(INPUT_GET, 'alg', FILTER_SANITIZE_STRING), "alg" => filter_input(INPUT_GET, 'alg', FILTER_SANITIZE_STRING),
"state" => filter_input(INPUT_GET, 'state', FILTER_SANITIZE_STRING), "state" => filter_input(INPUT_GET, 'state', FILTER_SANITIZE_STRING),
"scope" => filter_input(INPUT_GET, 'scope', FILTER_SANITIZE_STRING) "scope" => filter_input(INPUT_GET, 'scope', FILTER_SANITIZE_STRING),
"nonce" => filter_input(INPUT_GET, 'nonce', FILTER_SANITIZE_STRING)
]; ];
$requestHandler = new \RAP\OAuth2RequestHandler($locator); $requestHandler = new \RAP\OAuth2RequestHandler($locator);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment