Commit 941d4231 authored by Sonia Zorba's avatar Sonia Zorba
Browse files

Removed support for external JWKS (used by old portals)

parent e80c791f
Loading
Loading
Loading
Loading
+0 −61
Original line number Original line Diff line number Diff line
@@ -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;
    }

}
}
+2 −56
Original line number Original line Diff line number Diff line
@@ -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
 */
 */
@@ -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;
    }

}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -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;
+0 −4
Original line number Original line Diff line number Diff line
@@ -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);
}
}
+0 −44
Original line number Original line Diff line number Diff line
@@ -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