Skip to content

Instantly share code, notes, and snippets.

@summersab
Created October 22, 2021 21:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save summersab/a623f0b56ba23f87bc92d3abe0a840fc to your computer and use it in GitHub Desktop.
Save summersab/a623f0b56ba23f87bc92d3abe0a840fc to your computer and use it in GitHub Desktop.
A simple Keykloak REST API wrapper
<?php
class KeycloakApiClient
{
private $secret;
public $token;
private $base_url;
public function __construct($secret, $base_url) {
$this->secret = $secret;
$this->base_url = $base_url;
$this->token = refreshToken();
}
public function get($url = "", $post = null) {
return $this->go("GET", $url, $post);
}
public function post($url, $post = null) {
return $this->go("POST", $url, $post);
}
public function put($url, $post = null) {
return $this->go("PUT", $url, $post);
}
public function delete($url, $post = null) {
return $this->go("DELETE", $url, $post);
}
public function go($method, $url, $post) {
if (is_null($this->token)) {
$this->refreshToken();
}
if (!is_array($post)) {
$post = null;
}
if (!$url) {
throw new \Exception("Please enter a destination url");
}
$url = $this->base_url . "/" . $url;
$headers = $this->getHeaders();
//GET Override
if ($method == "GET" && $post !== null) {
$url .= (strpos($url, "?") === false ? "?" : "") . http_build_query($post);
$post = "";
}
//Setup cURL
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
if ($post) {
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post));
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = trim(curl_exec($ch));
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
$info = curl_getinfo($ch);
$json = json_decode($response, 1);
if (!is_array($json)) {
return $response;
}
return $json;
}
//Get auth headers for this call
public function getHeaders() {
return array(
"Authorization: Bearer $this->token",
"Content-Type: application/json",
);
}
private function refreshToken() {
$ch = curl_init();
$postfields = "grant_type=client_credentials&" . "client_id=admin-cli&" . "client_secret=$this->secret";
curl_setopt($ch, CURLOPT_URL, $this->base_url . '/auth/realms/master/protocol/openid-connect/token');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$headers = array();
$headers[] = 'Content-Type: application/x-www-form-urlencoded';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close($ch);
return json_decode($result, true)['access_token'];
}
}
$kc = new KeycloakApiClient('12345678-90ab-cdef-1234-567890abcdef', 'https://login.mydomain.com');
// This works
$result = $kc->get('auth/realms/master');
echo print_r($result, true) . "\n";
// This does not
$result = $kc->get('auth/realms/master/clients');
echo print_r($result, true) . "\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment