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

Removed support for external JWKS (used by old portals)

parent e80c791f
No related branches found
No related tags found
No related merge requests found
......@@ -77,65 +77,4 @@ class JWKSHandler {
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;
}
}
......@@ -24,8 +24,6 @@
namespace RAP;
use \Firebase\JWT\JWT;
/**
* See https://tools.ietf.org/html/rfc8693
*/
......@@ -92,56 +90,4 @@ class TokenExchanger {
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;
}
}
......@@ -102,7 +102,7 @@ class UserHandler {
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);
$remainingUser = $userId1 === $remainingUserId ? $user1 : $user2;
......
......@@ -11,8 +11,4 @@ interface JWKSDAO {
public function insertRSAKeyPair(RSAKeyPair $keyPair): RSAKeyPair;
public function getNewestKeyPair(): ?RSAKeyPair;
public function getAllPublicJWK(): array;
public function updatePublicJWK(PublicJWK $jwk);
}
......@@ -85,48 +85,4 @@ class MySQLJWKSDAO extends BaseMySQLDAO implements JWKSDAO {
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();
}
}
......@@ -35,7 +35,6 @@ class BrowserBasedOAuth2Client extends BrowserBasedClient {
public $scope;
public $homePage;
public $showInHome;
public $jwks;
public $scopeAudienceMap = [];
public function __construct(object $config) {
......@@ -48,7 +47,6 @@ class BrowserBasedOAuth2Client extends BrowserBasedClient {
$this->homePage = isset($config->home) ? $config->home : null;
$this->showInHome = isset($config->showInHome) ? $config->showInHome : false;
$this->authMethods = $config->methods;
$this->jwks = isset($config->jwks) ? $config->jwks : null;
$this->scopeAudienceMap = isset($config->scopeAudienceMap) ? $config->scopeAudienceMap : null;
}
......
<?php
namespace RAP;
class PublicJWK {
public $kid;
public $key;
public $url;
public $updateTime;
}
......@@ -59,7 +59,6 @@ clients:
icon:
showInHome: true
methods: [eduGAIN, Google, Facebook, LinkedIn, X.509, LocalIdP]
jwks:
- label: "Asiago Astrophysical Observatory (localhost)"
id: aao-dev
secret: 2a97516c354b68848cdbd8f54a226a0a55b21ed138e207ad6c5cbb9c00aa5aea
......@@ -69,7 +68,6 @@ clients:
icon: asiago.gif
showInHome: true
methods: [eduGAIN, Google, Facebook, LinkedIn, X.509, LocalIdP]
jwks: http://localhost:8081/aao/jwks
cliClients:
- id: gms_cli
secret: 2a97516c354b68848cdbd8f54a226a0a55b21ed138e207ad6c5cbb9c00aa5aea
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment