From 5fb12e193a49882598d4e966c1f836aa8c369d5d Mon Sep 17 00:00:00 2001 From: Gayan Liyanagamage Date: Mon, 25 May 2020 11:38:53 +0530 Subject: [PATCH] using keycloak id instead of client id --- pom.xml | 2 +- .../wso2/keycloak/client/KeycloakClient.java | 70 ++++++++++++++++--- 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 90ca63a..67029eb 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 4.0.0 org.wso2.carbon apim-keymanager-keycloak - 1.0.1 + 1.0.2 bundle Client implementation to integrate with Keycloak Authorization Server http://wso2.org diff --git a/src/main/java/org/wso2/keycloak/client/KeycloakClient.java b/src/main/java/org/wso2/keycloak/client/KeycloakClient.java index 0e2559e..f85039e 100644 --- a/src/main/java/org/wso2/keycloak/client/KeycloakClient.java +++ b/src/main/java/org/wso2/keycloak/client/KeycloakClient.java @@ -125,7 +125,8 @@ public OAuthApplicationInfo createApplication(OAuthAppRequest oAuthAppRequest) t // If successful a 201 will be returned with no body if (HttpStatus.SC_CREATED == statusCode) { - String clientSecret = getClientSecret(clientName); + String keycloakId = getKeycloakId(clientName); + String clientSecret = getClientSecret(keycloakId); JSONObject clientInfoJsonObject = getClientById(clientName); oAuthApplicationInfo = createOAuthAppInfoFromResponse(clientInfoJsonObject); oAuthApplicationInfo.addParameter(KeycloakConstants.TOKEN_SCOPE, scope); @@ -154,11 +155,13 @@ public OAuthApplicationInfo updateApplication(OAuthAppRequest oAuthAppRequest) t log.debug(String.format("Updating an OAuth client in Keycloak authorization server for the Consumer Key %s", clientId)); } + // Get Keycloak Id + String keycloakId = getKeycloakId(clientId); // Getting Client Instance Url and API Key from Config. String keyCloakInstanceUrl = configuration.getParameter(KeycloakConstants.KEYCLOAK_INSTANCE_URL); String keycloakRealm = configuration.getParameter(KeycloakConstants.KEYCLOAK_REALM_NAME); String registrationEndpoint = keyCloakInstanceUrl + KeycloakConstants.KEYCLOAK_ADMIN_CONTEXT + keycloakRealm + - KeycloakConstants.CLIENT_ENDPOINT + clientId; + KeycloakConstants.CLIENT_ENDPOINT + keycloakId; Map paramMap = new HashMap(); if (StringUtils.isNotEmpty(clientId)) { @@ -182,7 +185,7 @@ public OAuthApplicationInfo updateApplication(OAuthAppRequest oAuthAppRequest) t HttpResponse response = httpClient.execute(httpPut); int statusCode = response.getStatusLine().getStatusCode(); if (statusCode == HttpStatus.SC_NO_CONTENT){ - String clientSecret = getClientSecret(clientId); + String clientSecret = getClientSecret(keycloakId); JSONObject clientInfoJsonObject = getClientById(clientId); oAuthApplicationInfo = createOAuthAppInfoFromResponse(clientInfoJsonObject); oAuthApplicationInfo.addParameter(KeycloakConstants.CLIENT_SECRET, clientSecret); @@ -207,10 +210,11 @@ public void deleteApplication(String clientId) throws APIManagementException { clientId)); } // Getting Client Instance Url and API Key from Config. + String keycloakId = getKeycloakId(clientId); String keyCloakInstanceUrl = configuration.getParameter(KeycloakConstants.KEYCLOAK_INSTANCE_URL); String keycloakRealm = configuration.getParameter(KeycloakConstants.KEYCLOAK_REALM_NAME); String registrationEndpoint = keyCloakInstanceUrl + KeycloakConstants.KEYCLOAK_ADMIN_CONTEXT + keycloakRealm + - KeycloakConstants.CLIENT_ENDPOINT + clientId; + KeycloakConstants.CLIENT_ENDPOINT + keycloakId; String accessToken = getAccessToken(); try (CloseableHttpClient httpClient = HttpClientBuilder.create().build();) { @@ -238,7 +242,8 @@ public void deleteApplication(String clientId) throws APIManagementException { @Override public OAuthApplicationInfo retrieveApplication(String clientId) throws APIManagementException { OAuthApplicationInfo oAuthApplicationInfo; - String clientSecret = getClientSecret(clientId); + String keycloakId = getKeycloakId(clientId); + String clientSecret = getClientSecret(keycloakId); JSONObject clientInfoJsonObject = getClientById(clientId); oAuthApplicationInfo = createOAuthAppInfoFromResponse(clientInfoJsonObject); oAuthApplicationInfo.setClientSecret(clientSecret); @@ -302,7 +307,8 @@ public AccessTokenInfo getTokenMetaData(String accessToken) throws APIManagement } handleException("Invalid JWT token. Failed to decode the token."); } - String clientSecret = getClientSecret(clientId); + String keycloakId = getKeycloakId(clientId); + String clientSecret = getClientSecret(keycloakId); AccessTokenInfo tokenInfo = new AccessTokenInfo(); String keyCloakInstanceUrl = configuration.getParameter(KeycloakConstants.KEYCLOAK_INSTANCE_URL); String keycloakRealm = configuration.getParameter(KeycloakConstants.KEYCLOAK_REALM_NAME); @@ -562,7 +568,7 @@ private String createJsonPayloadFromOauthApplication(OAuthApplicationInfo oAuthA if (StringUtils.isNotEmpty(clientId)) { paramMap.put(KeycloakConstants.KEYCLOAK_CLIENT_ID, clientId); - paramMap.put(KeycloakConstants.KEYCLOAK_ID, clientId); + //paramMap.put(KeycloakConstants.KEYCLOAK_ID, clientId); } String clientRedirectUri = oAuthApplicationInfo.getCallBackURL(); @@ -628,7 +634,15 @@ private JSONObject getParsedObjectByReader(BufferedReader reader) throws ParseEx JSONObject parsedObject = null; JSONParser parser = new JSONParser(); if (reader != null) { - parsedObject = (JSONObject) parser.parse(reader); + Object object = parser.parse(reader); + + if(object instanceof JSONArray) { + JSONArray jsonArray = (JSONArray) object; + parsedObject = (JSONObject)jsonArray.get(0); + } else { + parsedObject = (JSONObject)object; + } + } return parsedObject; } @@ -816,7 +830,43 @@ private String getClientSecret(String clientId) throws APIManagementException{ } return null; } - + + /** + * This method returns the Keycloak id with the given clientId in Keycloak + * @param clientId Client id of a client in Keycloak + * @return Keycloak id + * @throws APIManagementException This is the custom exception class for API management + */ + private String getKeycloakId(String clientId) throws APIManagementException{ + String accessToken = getAccessToken(); + String keyCloakInstanceUrl = configuration.getParameter(KeycloakConstants.KEYCLOAK_INSTANCE_URL); + String keycloakRealm = configuration.getParameter(KeycloakConstants.KEYCLOAK_REALM_NAME); + String clientSecretEndpoint = keyCloakInstanceUrl + KeycloakConstants.KEYCLOAK_ADMIN_CONTEXT + keycloakRealm + + KeycloakConstants.CLIENT_ENDPOINT + "?clientId=" + clientId; + try (CloseableHttpClient httpClient = HttpClientBuilder.create().build();) { + HttpGet httpGet = new HttpGet(clientSecretEndpoint); + httpGet.setHeader(KeycloakConstants.AUTHORIZATION, KeycloakConstants.AUTHENTICATION_BEARER + accessToken); + HttpResponse response = httpClient.execute(httpGet); + int statusCode = response.getStatusLine().getStatusCode(); + if (HttpStatus.SC_OK == statusCode) { + HttpEntity entity = response.getEntity(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), KeycloakConstants.UTF_8));) { + JSONObject responseJSON = getParsedObjectByReader(reader); + return (String)responseJSON.get(KeycloakConstants.KEYCLOAK_ID); + } + } + } catch (ParseException e) { + handleException(KeycloakConstants.ERROR_WHILE_PARSE_RESPONSE, e); + } catch (UnsupportedEncodingException e) { + handleException(KeycloakConstants.ERROR_ENCODING_METHOD_NOT_SUPPORTED, e); + } catch (ClientProtocolException e) { + handleException("HTTP request error has occurred while sending request to OAuth provider. ", e); + } catch (IOException e) { + handleException(KeycloakConstants.ERROR_OCCURRED_WHILE_READ_OR_CLOSE_BUFFER_READER, e); + } + return null; + } + /** * This method returns the client representation related of a client with the given clientId in Keycloak * @param clientId Client id of a client in Keycloak @@ -828,7 +878,7 @@ private JSONObject getClientById(String clientId) throws APIManagementException{ String keyCloakInstanceUrl = configuration.getParameter(KeycloakConstants.KEYCLOAK_INSTANCE_URL); String keycloakRealm = configuration.getParameter(KeycloakConstants.KEYCLOAK_REALM_NAME); String clientSecretEndpoint = keyCloakInstanceUrl + KeycloakConstants.KEYCLOAK_ADMIN_CONTEXT + keycloakRealm + - KeycloakConstants.CLIENT_ENDPOINT + clientId; + KeycloakConstants.CLIENT_ENDPOINT + "?clientId=" + clientId; try (CloseableHttpClient httpClient = HttpClientBuilder.create().build();) { HttpGet httpGet = new HttpGet(clientSecretEndpoint); httpGet.setHeader(KeycloakConstants.AUTHORIZATION, KeycloakConstants.AUTHENTICATION_BEARER + accessToken);