Loading classes/JWKSHandler.php +0 −61 Original line number Original line Diff line number Diff line Loading @@ -77,65 +77,4 @@ class JWKSHandler { return $matches[1]; return $matches[1]; } } public function loadAllJWKS(): array { foreach ($this->locator->getBrowserBasedOAuth2Clients() as $client) { if ($client->jwks !== null) { $this->loadJWKS($client->jwks); } } $dao = $this->locator->getJWKSDAO(); return $dao->getAllPublicJWK(); } private function loadJWKS($url) { $dao = $this->locator->getJWKSDAO(); $conn = curl_init($url); curl_setopt($conn, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($conn, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($conn); $info = curl_getinfo($conn); if ($info['http_code'] === 200) { $jwks = json_decode($result, TRUE); foreach ($jwks['keys'] as $key) { $key['url'] = $url; $jwk = $this->getPublicJWK($key); $dao->updatePublicJWK($jwk); } } else { error_log('Error while retrieving JWKS from ' . $url); } curl_close($conn); } private function getPublicJWK($data): PublicJWK { // Convert Base64 uri-safe variant to default (needed for JWKS) $n = strtr($data['n'], '-_', '+/'); $rsa = new RSA(); $key = "<RSAKeyPair>" . "<Modulus>" . $n . "</Modulus>" . "<Exponent>" . $data['e'] . "</Exponent>" . "</RSAKeyPair>"; $rsa->loadKey($key, RSA::PUBLIC_FORMAT_XML); $jwk = new PublicJWK(); $jwk->kid = $data['kid']; $jwk->key = $rsa; $jwk->url = $data['url']; $jwk->updateTime = time(); return $jwk; } } } classes/TokenExchanger.php +2 −56 Original line number Original line Diff line number Diff line Loading @@ -24,8 +24,6 @@ namespace RAP; namespace RAP; use \Firebase\JWT\JWT; /** /** * See https://tools.ietf.org/html/rfc8693 * See https://tools.ietf.org/html/rfc8693 */ */ Loading Loading @@ -92,56 +90,4 @@ class TokenExchanger { return $audiences; return $audiences; } } /** * DEPRECATED (currently used by portals: to be removed) */ public function exchangeTokenOld(string $token) { $key = $this->getExternalKeyForToken($token); $decoded = JWT::decode($token, $key->key, ['RS256']); $subject = $decoded->sub; $lifespan = ($decoded->exp - time()); $data = []; $data['access_token'] = $this->locator->getTokenBuilder()->generateNewToken($subject, $lifespan / 3600, "gms"); $data['issued_token_type'] = "urn:ietf:params:oauth:token-type:access_token"; $data['token_type'] = 'Bearer'; $data['expires_in'] = $lifespan; return $data; } private function getExternalKeyForToken(string $token): PublicJWK { $keys = $this->locator->getJWKSDAO()->getAllPublicJWK(); $parts = explode('.', $token); $head = JWT::jsonDecode(JWT::urlsafeB64Decode($parts[0])); $kid = $head->kid; $key = $this->getKeyByKid($keys, $kid); if ($key === null) { $keys = $this->locator->getJWKSHandler()->loadAllJWKS(); } $key = $this->getKeyByKid($keys, $kid); if ($key !== null) { return $key; } throw new \Exception("Invalid kid"); } private function getKeyByKid(array $keys, string $kid): ?PublicJWK { foreach ($keys as $key) { if ($key->kid === $kid) { return $key; } } return null; } } } classes/UserHandler.php +1 −1 Original line number Original line Diff line number Diff line Loading @@ -102,7 +102,7 @@ class UserHandler { return $this->joinNewIdentity($user1, $user2); return $this->joinNewIdentity($user1, $user2); } } // Call Grouper for moving groups and privileges from one user to the other // Call GMS for moving groups and privileges from one user to the other $remainingUserId = $this->locator->getGmsClient()->joinGroups($userId1, $userId2); $remainingUserId = $this->locator->getGmsClient()->joinGroups($userId1, $userId2); $remainingUser = $userId1 === $remainingUserId ? $user1 : $user2; $remainingUser = $userId1 === $remainingUserId ? $user1 : $user2; Loading classes/datalayer/JWKSDAO.php +0 −4 Original line number Original line Diff line number Diff line Loading @@ -11,8 +11,4 @@ interface JWKSDAO { public function insertRSAKeyPair(RSAKeyPair $keyPair): RSAKeyPair; public function insertRSAKeyPair(RSAKeyPair $keyPair): RSAKeyPair; public function getNewestKeyPair(): ?RSAKeyPair; public function getNewestKeyPair(): ?RSAKeyPair; public function getAllPublicJWK(): array; public function updatePublicJWK(PublicJWK $jwk); } } classes/datalayer/mysql/MySQLJWKSDAO.php +0 −44 Original line number Original line Diff line number Diff line Loading @@ -85,48 +85,4 @@ class MySQLJWKSDAO extends BaseMySQLDAO implements JWKSDAO { return $keyPair; return $keyPair; } } public function getAllPublicJWK(): array { $dbh = $this->getDBHandler(); $query = "SELECT `kid`, `key`, `url`, `update_time` FROM public_jwk"; $stmt = $dbh->prepare($query); $stmt->execute(); $keys = []; foreach ($stmt->fetchAll() as $row) { array_push($keys, $this->getPublicJWKFromResultRow($row)); } return $keys; } private function getPublicJWKFromResultRow($row): PublicJWK { $jwk = new PublicJWK (); $jwk->key = $row['key']; $jwk->kid = $row['kid']; $jwk->url = $row['url']; $jwk->updateTime = $row['update_time']; return $jwk; } public function updatePublicJWK(PublicJWK $jwk) { $dbh = $this->getDBHandler(); $query = "INSERT INTO public_jwk(kid, `key`, `url`, update_time) VALUES (:kid, :key, :url, :update_time)" . " ON DUPLICATE KEY UPDATE `key`=:key, `url`=:url, update_time=:update_time"; $stmt = $dbh->prepare($query); $stmt->bindParam(':kid', $jwk->kid); $stmt->bindParam(':key', $jwk->key); $stmt->bindParam(':url', $jwk->url); $stmt->bindParam(':update_time', $jwk->updateTime); $stmt->execute(); } } } Loading
classes/JWKSHandler.php +0 −61 Original line number Original line Diff line number Diff line Loading @@ -77,65 +77,4 @@ class JWKSHandler { return $matches[1]; return $matches[1]; } } public function loadAllJWKS(): array { foreach ($this->locator->getBrowserBasedOAuth2Clients() as $client) { if ($client->jwks !== null) { $this->loadJWKS($client->jwks); } } $dao = $this->locator->getJWKSDAO(); return $dao->getAllPublicJWK(); } private function loadJWKS($url) { $dao = $this->locator->getJWKSDAO(); $conn = curl_init($url); curl_setopt($conn, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($conn, CURLOPT_RETURNTRANSFER, true); $result = curl_exec($conn); $info = curl_getinfo($conn); if ($info['http_code'] === 200) { $jwks = json_decode($result, TRUE); foreach ($jwks['keys'] as $key) { $key['url'] = $url; $jwk = $this->getPublicJWK($key); $dao->updatePublicJWK($jwk); } } else { error_log('Error while retrieving JWKS from ' . $url); } curl_close($conn); } private function getPublicJWK($data): PublicJWK { // Convert Base64 uri-safe variant to default (needed for JWKS) $n = strtr($data['n'], '-_', '+/'); $rsa = new RSA(); $key = "<RSAKeyPair>" . "<Modulus>" . $n . "</Modulus>" . "<Exponent>" . $data['e'] . "</Exponent>" . "</RSAKeyPair>"; $rsa->loadKey($key, RSA::PUBLIC_FORMAT_XML); $jwk = new PublicJWK(); $jwk->kid = $data['kid']; $jwk->key = $rsa; $jwk->url = $data['url']; $jwk->updateTime = time(); return $jwk; } } }
classes/TokenExchanger.php +2 −56 Original line number Original line Diff line number Diff line Loading @@ -24,8 +24,6 @@ namespace RAP; namespace RAP; use \Firebase\JWT\JWT; /** /** * See https://tools.ietf.org/html/rfc8693 * See https://tools.ietf.org/html/rfc8693 */ */ Loading Loading @@ -92,56 +90,4 @@ class TokenExchanger { return $audiences; return $audiences; } } /** * DEPRECATED (currently used by portals: to be removed) */ public function exchangeTokenOld(string $token) { $key = $this->getExternalKeyForToken($token); $decoded = JWT::decode($token, $key->key, ['RS256']); $subject = $decoded->sub; $lifespan = ($decoded->exp - time()); $data = []; $data['access_token'] = $this->locator->getTokenBuilder()->generateNewToken($subject, $lifespan / 3600, "gms"); $data['issued_token_type'] = "urn:ietf:params:oauth:token-type:access_token"; $data['token_type'] = 'Bearer'; $data['expires_in'] = $lifespan; return $data; } private function getExternalKeyForToken(string $token): PublicJWK { $keys = $this->locator->getJWKSDAO()->getAllPublicJWK(); $parts = explode('.', $token); $head = JWT::jsonDecode(JWT::urlsafeB64Decode($parts[0])); $kid = $head->kid; $key = $this->getKeyByKid($keys, $kid); if ($key === null) { $keys = $this->locator->getJWKSHandler()->loadAllJWKS(); } $key = $this->getKeyByKid($keys, $kid); if ($key !== null) { return $key; } throw new \Exception("Invalid kid"); } private function getKeyByKid(array $keys, string $kid): ?PublicJWK { foreach ($keys as $key) { if ($key->kid === $kid) { return $key; } } return null; } } }
classes/UserHandler.php +1 −1 Original line number Original line Diff line number Diff line Loading @@ -102,7 +102,7 @@ class UserHandler { return $this->joinNewIdentity($user1, $user2); return $this->joinNewIdentity($user1, $user2); } } // Call Grouper for moving groups and privileges from one user to the other // Call GMS for moving groups and privileges from one user to the other $remainingUserId = $this->locator->getGmsClient()->joinGroups($userId1, $userId2); $remainingUserId = $this->locator->getGmsClient()->joinGroups($userId1, $userId2); $remainingUser = $userId1 === $remainingUserId ? $user1 : $user2; $remainingUser = $userId1 === $remainingUserId ? $user1 : $user2; Loading
classes/datalayer/JWKSDAO.php +0 −4 Original line number Original line Diff line number Diff line Loading @@ -11,8 +11,4 @@ interface JWKSDAO { public function insertRSAKeyPair(RSAKeyPair $keyPair): RSAKeyPair; public function insertRSAKeyPair(RSAKeyPair $keyPair): RSAKeyPair; public function getNewestKeyPair(): ?RSAKeyPair; public function getNewestKeyPair(): ?RSAKeyPair; public function getAllPublicJWK(): array; public function updatePublicJWK(PublicJWK $jwk); } }
classes/datalayer/mysql/MySQLJWKSDAO.php +0 −44 Original line number Original line Diff line number Diff line Loading @@ -85,48 +85,4 @@ class MySQLJWKSDAO extends BaseMySQLDAO implements JWKSDAO { return $keyPair; return $keyPair; } } public function getAllPublicJWK(): array { $dbh = $this->getDBHandler(); $query = "SELECT `kid`, `key`, `url`, `update_time` FROM public_jwk"; $stmt = $dbh->prepare($query); $stmt->execute(); $keys = []; foreach ($stmt->fetchAll() as $row) { array_push($keys, $this->getPublicJWKFromResultRow($row)); } return $keys; } private function getPublicJWKFromResultRow($row): PublicJWK { $jwk = new PublicJWK (); $jwk->key = $row['key']; $jwk->kid = $row['kid']; $jwk->url = $row['url']; $jwk->updateTime = $row['update_time']; return $jwk; } public function updatePublicJWK(PublicJWK $jwk) { $dbh = $this->getDBHandler(); $query = "INSERT INTO public_jwk(kid, `key`, `url`, update_time) VALUES (:kid, :key, :url, :update_time)" . " ON DUPLICATE KEY UPDATE `key`=:key, `url`=:url, update_time=:update_time"; $stmt = $dbh->prepare($query); $stmt->bindParam(':kid', $jwk->kid); $stmt->bindParam(':key', $jwk->key); $stmt->bindParam(':url', $jwk->url); $stmt->bindParam(':update_time', $jwk->updateTime); $stmt->execute(); } } }