You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2017/06/16 20:36:25 UTC
[22/50] [abbrv] airavata-php-gateway git commit: AIRAVATA-2342
Keycloak: implement password grant type flow
AIRAVATA-2342 Keycloak: implement password grant type flow
Project: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/repo
Commit: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/commit/e9f3b24a
Tree: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/tree/e9f3b24a
Diff: http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/diff/e9f3b24a
Branch: refs/heads/develop
Commit: e9f3b24a04bf5e2353039b31779578aaad25418d
Parents: 60951a2
Author: Marcus Christie <ma...@iu.edu>
Authored: Thu Apr 27 12:17:44 2017 -0400
Committer: Marcus Christie <ma...@iu.edu>
Committed: Thu Apr 27 12:17:44 2017 -0400
----------------------------------------------------------------------
app/controllers/AccountController.php | 16 ++-----
.../Keycloak/API/BaseKeycloakAPIEndpoint.php | 49 +++++++++++++++++++
app/libraries/Keycloak/API/RoleMapper.php | 50 ++------------------
app/libraries/Keycloak/API/Roles.php | 45 +-----------------
app/libraries/Keycloak/API/Users.php | 49 ++-----------------
app/libraries/Keycloak/Keycloak.php | 45 ++++++++++++++++++
6 files changed, 107 insertions(+), 147 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e9f3b24a/app/controllers/AccountController.php
----------------------------------------------------------------------
diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php
index 7900c7c..303c3b4 100644
--- a/app/controllers/AccountController.php
+++ b/app/controllers/AccountController.php
@@ -99,32 +99,22 @@ class AccountController extends BaseController
{
if (CommonUtilities::form_submitted()) {
$wsisConfig = Config::get('pga_config.wsis');
- if( $wsisConfig['tenant-domain'] == "")
- $username = Input::get("username");
- else
- $username = Input::get("username") . "@" . $wsisConfig['tenant-domain'];
+ $username = Input::get("username");
$password = $_POST['password'];
- $response = WSIS::authenticate($username, $password);
+ $response = Keycloak::authenticate($username, $password);
if(!isset($response->access_token)){
return Redirect::to("login")->with("invalid-credentials", true);
}
$accessToken = $response->access_token;
$refreshToken = $response->refresh_token;
- $expirationTime = time() + $response->expires_in - 5; //5 seconds safe margin
+ $expirationTime = time() + $response->expires_in - 300; // 5 minutes safe margin
$userProfile = Keycloak::getUserProfileFromOAuthToken($accessToken);
$username = $userProfile['username'];
$userRoles = $userProfile['roles'];
- //FIXME There is a bug in WSO2 IS which doest not return the admin role for the default admin user.
- //FIXME Hence as a workaround we manually add it here.
- if ($username == Config::get('pga_config.wsis')['admin-username']
- || $username == Config::get('pga_config.wsis')['admin-username'] . '@' . Config::get('pga_config.wsis')['tenant-domain']){
- $userRoles[] = Config::get('pga_config.wsis')['admin-role-name'];
- }
-
$authzToken = new Airavata\Model\Security\AuthzToken();
$authzToken->accessToken = $accessToken;
$authzToken->claimsMap['gatewayID'] = Config::get('pga_config.airavata')['gateway-id'];
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e9f3b24a/app/libraries/Keycloak/API/BaseKeycloakAPIEndpoint.php
----------------------------------------------------------------------
diff --git a/app/libraries/Keycloak/API/BaseKeycloakAPIEndpoint.php b/app/libraries/Keycloak/API/BaseKeycloakAPIEndpoint.php
new file mode 100644
index 0000000..c440179
--- /dev/null
+++ b/app/libraries/Keycloak/API/BaseKeycloakAPIEndpoint.php
@@ -0,0 +1,49 @@
+<?php
+namespace Keycloak\API;
+
+use Exception;
+use Log;
+
+class BaseKeycloakAPIEndpoint {
+
+ protected $base_endpoint_url;
+ protected $admin_username;
+ protected $admin_password;
+ protected $verify_peer;
+
+ function __construct($base_endpoint_url, $admin_username, $admin_password, $verify_peer) {
+ $this->base_endpoint_url = $base_endpoint_url;
+ $this->admin_username = $admin_username;
+ $this->admin_password = $admin_password;
+ $this->verify_peer = $verify_peer;
+ }
+
+ protected function getAPIAccessToken($realm) {
+
+ // http://www.keycloak.org/docs/2.5/server_development/topics/admin-rest-api.html
+ // curl -d client_id=admin-cli -d username=username \
+ // -d "password=password" -d grant_type=password https://149.165.156.62:8443/auth/realms/master/protocol/openid-connect/token
+
+ $r = curl_init($this->base_endpoint_url . '/realms/' . rawurlencode($realm) . '/protocol/openid-connect/token');
+ curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($r, CURLOPT_ENCODING, 1);
+ curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
+
+ // Assemble POST parameters for the request.
+ $post_fields = "client_id=admin-cli&username=" . urlencode($this->admin_username) . "&password=" . urlencode($this->admin_password) . "&grant_type=password";
+
+ // Obtain and return the access token from the response.
+ curl_setopt($r, CURLOPT_POST, true);
+ curl_setopt($r, CURLOPT_POSTFIELDS, $post_fields);
+
+ $response = curl_exec($r);
+ if ($response == false) {
+ Log::error("Failed to retrieve API Access Token");
+ die("curl_exec() failed. Error: " . curl_error($r));
+ }
+
+ $result = json_decode($response);
+ // Log::debug("API Access Token result", array($result));
+ return $result->access_token;
+ }
+}
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e9f3b24a/app/libraries/Keycloak/API/RoleMapper.php
----------------------------------------------------------------------
diff --git a/app/libraries/Keycloak/API/RoleMapper.php b/app/libraries/Keycloak/API/RoleMapper.php
index 18a477b..f2fab42 100644
--- a/app/libraries/Keycloak/API/RoleMapper.php
+++ b/app/libraries/Keycloak/API/RoleMapper.php
@@ -10,19 +10,7 @@ use Log;
* This class provide an easy to use interface for
* the Keycloak RoleMapper REST API.
*/
-class RoleMapper {
-
- private $base_endpoint_url;
- private $admin_username;
- private $admin_password;
- private $verify_peer;
-
- public function __construct($base_endpoint_url, $admin_username, $admin_password, $verify_peer) {
- $this->base_endpoint_url = $base_endpoint_url;
- $this->admin_username = $admin_username;
- $this->admin_password = $admin_password;
- $this->verify_peer = $verify_peer;
- }
+class RoleMapper extends BaseKeycloakAPIEndpoint {
/**
* Get realm-level role mappings for a user
@@ -35,7 +23,7 @@ class RoleMapper {
// curl -H "Authorization: bearer $access_token" https://149.165.156.62:8443/auth/admin/realms/airavata/users/2c9ad2c6-0212-4aef-a5fb-9df862578934/role-mappings/realm
// get access token for admin API
- $access_token = $this->getAPIAccessToken();
+ $access_token = $this->getAPIAccessToken($realm);
$url = $this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users/' . rawurlencode($user_id) . '/role-mappings/realm';
// Log::debug("getRealmRoleMappingsForUser url", array($url));
$r = curl_init($url);
@@ -63,7 +51,7 @@ class RoleMapper {
public function addRealmRoleMappingsToUser($realm, $user_id, $role_representations) {
// get access token for admin API
- $access_token = $this->getAPIAccessToken();
+ $access_token = $this->getAPIAccessToken($realm);
$url = $this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users/' . rawurlencode($user_id) . '/role-mappings/realm';
// Log::debug("addRealmRoleMappingsToUser", array($url, $role_representations));
$r = curl_init($url);
@@ -96,7 +84,7 @@ class RoleMapper {
public function deleteRealmRoleMappingsToUser($realm, $user_id, $role_representations) {
// get access token for admin API
- $access_token = $this->getAPIAccessToken();
+ $access_token = $this->getAPIAccessToken($realm);
$url = $this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users/' . rawurlencode($user_id) . '/role-mappings/realm';
// Log::debug("deleteRealmRoleMappingsToUser", array($url, $role_representations));
$r = curl_init($url);
@@ -122,34 +110,4 @@ class RoleMapper {
}
return;
}
-
- // TODO: factor this out into base class?
- private function getAPIAccessToken() {
-
- // http://www.keycloak.org/docs/2.5/server_development/topics/admin-rest-api.html
- // curl -d client_id=admin-cli -d username=username \
- // -d "password=password" -d grant_type=password https://149.165.156.62:8443/auth/realms/master/protocol/openid-connect/token
-
- $r = curl_init($this->base_endpoint_url . '/realms/master/protocol/openid-connect/token');
- curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($r, CURLOPT_ENCODING, 1);
- curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
-
- // Assemble POST parameters for the request.
- $post_fields = "client_id=admin-cli&username=" . urlencode($this->admin_username) . "&password=" . urlencode($this->admin_password) . "&grant_type=password";
-
- // Obtain and return the access token from the response.
- curl_setopt($r, CURLOPT_POST, true);
- curl_setopt($r, CURLOPT_POSTFIELDS, $post_fields);
-
- $response = curl_exec($r);
- if ($response == false) {
- Log::error("Failed to retrieve API Access Token");
- die("curl_exec() failed. Error: " . curl_error($r));
- }
-
- $result = json_decode($response);
- // Log::debug("API Access Token result", array($result));
- return $result->access_token;
- }
}
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e9f3b24a/app/libraries/Keycloak/API/Roles.php
----------------------------------------------------------------------
diff --git a/app/libraries/Keycloak/API/Roles.php b/app/libraries/Keycloak/API/Roles.php
index 02f5b8f..565b860 100644
--- a/app/libraries/Keycloak/API/Roles.php
+++ b/app/libraries/Keycloak/API/Roles.php
@@ -7,19 +7,7 @@ namespace Keycloak\API;
* This class provide an easy to use interface for
* the Keycloak Roles REST API.
*/
-class Roles {
-
- private $base_endpoint_url;
- private $admin_username;
- private $admin_password;
- private $verify_peer;
-
- public function __construct($base_endpoint_url, $admin_username, $admin_password, $verify_peer) {
- $this->base_endpoint_url = $base_endpoint_url;
- $this->admin_username = $admin_username;
- $this->admin_password = $admin_password;
- $this->verify_peer = $verify_peer;
- }
+class Roles extends BaseKeycloakAPIEndpoint {
/**
* Get representations of all of a realm's roles
@@ -29,7 +17,7 @@ class Roles {
public function getRoles($realm){
// get access token for admin API
- $access_token = $this->getAPIAccessToken();
+ $access_token = $this->getAPIAccessToken($realm);
$r = curl_init($this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/roles');
curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($r, CURLOPT_ENCODING, 1);
@@ -46,33 +34,4 @@ class Roles {
// Log::debug("getRealmRoleMappingsForUser result", array($result));
return $result;
}
-
- // TODO: factor this out into base class?
- private function getAPIAccessToken() {
-
- // http://www.keycloak.org/docs/2.5/server_development/topics/admin-rest-api.html
- // curl -d client_id=admin-cli -d username=username \
- // -d "password=password" -d grant_type=password https://149.165.156.62:8443/auth/realms/master/protocol/openid-connect/token
-
- $r = curl_init($this->base_endpoint_url . '/realms/master/protocol/openid-connect/token');
- curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($r, CURLOPT_ENCODING, 1);
- curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
-
- // Assemble POST parameters for the request.
- $post_fields = "client_id=admin-cli&username=" . urlencode($this->admin_username) . "&password=" . urlencode($this->admin_password) . "&grant_type=password";
-
- // Obtain and return the access token from the response.
- curl_setopt($r, CURLOPT_POST, true);
- curl_setopt($r, CURLOPT_POSTFIELDS, $post_fields);
-
- $response = curl_exec($r);
- if ($response == false) {
- die("curl_exec() failed. Error: " . curl_error($r));
- }
-
- $result = json_decode($response);
- // Log::debug("API Access Token result", array($result));
- return $result->access_token;
- }
}
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e9f3b24a/app/libraries/Keycloak/API/Users.php
----------------------------------------------------------------------
diff --git a/app/libraries/Keycloak/API/Users.php b/app/libraries/Keycloak/API/Users.php
index 089ad3a..d03be02 100644
--- a/app/libraries/Keycloak/API/Users.php
+++ b/app/libraries/Keycloak/API/Users.php
@@ -9,19 +9,7 @@ use Log;
* This class provide an easy to use interface for
* the Keycloak Users REST API.
*/
-class Users {
-
- private $base_endpoint_url;
- private $admin_username;
- private $admin_password;
- private $verify_peer;
-
- public function __construct($base_endpoint_url, $admin_username, $admin_password, $verify_peer) {
- $this->base_endpoint_url = $base_endpoint_url;
- $this->admin_username = $admin_username;
- $this->admin_password = $admin_password;
- $this->verify_peer = $verify_peer;
- }
+class Users extends BaseKeycloakAPIEndpoint {
/**
* Get representations of all users
@@ -31,7 +19,7 @@ class Users {
public function getUsers($realm, $username = null){
// get access token for admin API
- $access_token = $this->getAPIAccessToken();
+ $access_token = $this->getAPIAccessToken($realm);
$url = $this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users';
if ($username) {
$url = $url . '?username=' . rawurlencode($username);
@@ -64,7 +52,7 @@ class Users {
public function searchUsers($realm, $keyword){
// get access token for admin API
- $access_token = $this->getAPIAccessToken();
+ $access_token = $this->getAPIAccessToken($realm);
$url = $this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users?search=' . rawurlencode($keyword);
// Log::debug("getUsers url", array($url));
$r = curl_init($url);
@@ -92,7 +80,7 @@ class Users {
public function getUser($realm, $user_id) {
// get access token for admin API
- $access_token = $this->getAPIAccessToken();
+ $access_token = $this->getAPIAccessToken($realm);
$url = $this->base_endpoint_url . '/admin/realms/' . rawurlencode($realm) . '/users/' . rawurlencode($user_id);
// Log::debug("getUser url", array($url));
$r = curl_init($url);
@@ -111,33 +99,4 @@ class Users {
// Log::debug("getUsers result", array($result));
return $result;
}
-
- // TODO: factor this out into base class?
- private function getAPIAccessToken() {
-
- // http://www.keycloak.org/docs/2.5/server_development/topics/admin-rest-api.html
- // curl -d client_id=admin-cli -d username=username \
- // -d "password=password" -d grant_type=password https://149.165.156.62:8443/auth/realms/master/protocol/openid-connect/token
-
- $r = curl_init($this->base_endpoint_url . '/realms/master/protocol/openid-connect/token');
- curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($r, CURLOPT_ENCODING, 1);
- curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
-
- // Assemble POST parameters for the request.
- $post_fields = "client_id=admin-cli&username=" . urlencode($this->admin_username) . "&password=" . urlencode($this->admin_password) . "&grant_type=password";
-
- // Obtain and return the access token from the response.
- curl_setopt($r, CURLOPT_POST, true);
- curl_setopt($r, CURLOPT_POSTFIELDS, $post_fields);
-
- $response = curl_exec($r);
- if ($response == false) {
- die("curl_exec() failed. Error: " . curl_error($r));
- }
-
- $result = json_decode($response);
- // Log::debug("API Access Token result", array($result));
- return $result->access_token;
- }
}
http://git-wip-us.apache.org/repos/asf/airavata-php-gateway/blob/e9f3b24a/app/libraries/Keycloak/Keycloak.php
----------------------------------------------------------------------
diff --git a/app/libraries/Keycloak/Keycloak.php b/app/libraries/Keycloak/Keycloak.php
index 1f876b0..71706e5 100644
--- a/app/libraries/Keycloak/Keycloak.php
+++ b/app/libraries/Keycloak/Keycloak.php
@@ -43,6 +43,51 @@ class Keycloak {
$this->users = new Users($base_endpoint_url, $admin_username, $admin_password, $verify_peer);
}
+ /**
+ * Function to authenticate user
+ *
+ * @param string $username
+ * @param string $password
+ * @return boolean
+ * @throws Exception
+ */
+ public function authenticate($username, $password){
+
+ $config = $this->getOpenIDConnectDiscoveryConfiguration();
+ $token_endpoint = $config->token_endpoint;
+
+ // Init cUrl.
+ $r = curl_init($token_endpoint);
+ curl_setopt($r, CURLOPT_RETURNTRANSFER, 1);
+ // Decode compressed responses.
+ curl_setopt($r, CURLOPT_ENCODING, 1);
+ curl_setopt($r, CURLOPT_SSL_VERIFYPEER, $this->verify_peer);
+
+ // Add client ID and client secret to the headers.
+ curl_setopt($r, CURLOPT_HTTPHEADER, array(
+ "Authorization: Basic " . base64_encode($this->client_id . ":" . $this->client_secret),
+ ));
+
+ // Assemble POST parameters for the request.
+ $post_fields = "client_id=" . urlencode($this->client_id) . "&client_secret=" . urlencode($this->client_secret) . "&grant_type=password";
+ $post_fields .= "&username=" . urlencode($username) . "&password=" . urlencode($password);
+
+ // Obtain and return the access token from the response.
+ curl_setopt($r, CURLOPT_POST, true);
+ curl_setopt($r, CURLOPT_POSTFIELDS, $post_fields);
+
+ $response = curl_exec($r);
+ if ($response == false) {
+ die("curl_exec() failed. Error: " . curl_error($r));
+ }
+
+ //Parse JSON return object.
+ $result = json_decode($response);
+ // Log::debug("password grant type authenciation response", array($result));
+
+ return $result;
+ }
+
public function getOAuthRequestCodeUrl(){
$config = $this->getOpenIDConnectDiscoveryConfiguration();
$authorization_endpoint = $config->authorization_endpoint;