diff --git a/README.md b/README.md index 6e552bb..ec2bd98 100644 --- a/README.md +++ b/README.md @@ -71,11 +71,11 @@ CamundaOperateClient client = new CamundaOperateClient.Builder().authentication( .operateUrl("https://bru-2.operate.camunda.io/757dbc30-5127-4bed-XXXX-XXXXXXXXXXXX").build(); ``` -To connect to the **Local** Operate with **Identity & Keycloak**, you need to use the **LocalIdentityAuthentication**. The SaaSAuthentication requires the clientId and clientSecret. You can also change the Keycloak realm and the baseUrl depending on your installation. +To connect to the **Local** Operate with **Identity & Keycloak**, you need to use the **SelfManagedAuthentication**. The SelfManagedAuthentication requires the clientId and clientSecret. You can also change the Keycloak realm and the keycloakUrl depending on your installation. ```java -LocalIdentityAuthentication la = new LocalIdentityAuthentication().clientId("java").clientSecret("foTPogjlI0hidwbDZcYFWzmU8FOQwLx0").baseUrl("http://localhost:18080").keycloakRealm("camunda-platform"); -CamundaOperateClient client = new CamundaOperateClient.Builder().authentication(la) +SelfManagedAuthentication sma = new SelfManagedAuthentication().clientId("java").clientSecret("foTPogjlI0hidwbDZcYFWzmU8FOQwLx0").baseUrl("http://localhost:18080").keycloakRealm("camunda-platform"); +CamundaOperateClient client = new CamundaOperateClient.Builder().authentication(sma) .operateUrl("http://localhost:8081/").build(); ``` @@ -100,7 +100,7 @@ You can import it to your maven or gradle project as a dependency io.camunda camunda-operate-client-java - 1.2.2 + 1.3.0 ``` diff --git a/build.gradle b/build.gradle index 4aff4e7..eb7bc2d 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { } group = 'io.camunda' -version = '1.2.2' +version = '1.3.0' sourceCompatibility = '8' repositories { diff --git a/src/main/java/io/camunda/operate/auth/LocalIdentityAuthentication.java b/src/main/java/io/camunda/operate/auth/LocalIdentityAuthentication.java index 0a89237..9b702d9 100644 --- a/src/main/java/io/camunda/operate/auth/LocalIdentityAuthentication.java +++ b/src/main/java/io/camunda/operate/auth/LocalIdentityAuthentication.java @@ -15,6 +15,11 @@ import io.camunda.operate.exception.OperateException; import io.camunda.operate.util.JsonUtils; +/** + * This Class is used to authenticate against a Self-Managed Camunda 8 Operate. + * @deprecated replaced by {@link io.camunda.operate.auth.SelfManagedAuthentication} + */ +@Deprecated public class LocalIdentityAuthentication extends JwtAuthentication { private String clientId; diff --git a/src/main/java/io/camunda/operate/auth/SelfManagedAuthentication.java b/src/main/java/io/camunda/operate/auth/SelfManagedAuthentication.java new file mode 100644 index 0000000..f4a82af --- /dev/null +++ b/src/main/java/io/camunda/operate/auth/SelfManagedAuthentication.java @@ -0,0 +1,96 @@ +package io.camunda.operate.auth; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.net.HttpURLConnection; +import java.net.URL; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import com.fasterxml.jackson.databind.JsonNode; + +import io.camunda.operate.CamundaOperateClient; +import io.camunda.operate.exception.OperateException; +import io.camunda.operate.util.JsonUtils; + +/** + * This Class is used to authenticate against a Self-Managed Camunda 8 Operate. + */ +public class SelfManagedAuthentication extends JwtAuthentication { + + private String clientId; + private String clientSecret; + private String keycloakUrl = "http://localhost:18080"; + private String keycloakRealm = "camunda-platform"; + + public SelfManagedAuthentication() { + } + + public SelfManagedAuthentication(String clientId, String clientSecret) { + this.clientId = clientId; + this.clientSecret = clientSecret; + } + + public SelfManagedAuthentication clientId(String clientId) { + this.clientId = clientId; + return this; + } + public SelfManagedAuthentication clientSecret(String clientSecret) { + this.clientSecret = clientSecret; + return this; + } + public SelfManagedAuthentication keycloakUrl(String url) { + this.keycloakUrl = url; + return this; + } + public SelfManagedAuthentication keycloakRealm(String keycloakRealm) { + this.keycloakRealm = keycloakRealm; + return this; + } + + private String encode(String value) throws UnsupportedEncodingException { + return URLEncoder.encode(value, StandardCharsets.UTF_8.toString()); + } + + private String getConnectionString() throws UnsupportedEncodingException{ + return "grant_type=client_credentials&client_id="+encode(clientId)+"&client_secret="+encode(clientSecret); + } + + @Override + public void authenticate(CamundaOperateClient client) throws OperateException { + try { + URL url = new URL(this.keycloakUrl+"/auth/realms/"+keycloakRealm+"/protocol/openid-connect/token"); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + conn.setUseCaches(false); + conn.setConnectTimeout(1000 * 5); + conn.setDoOutput(true); + conn.setDoInput(true); + conn.setRequestMethod("POST"); + conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + + String data = getConnectionString(); + + conn.getOutputStream().write(data.getBytes(StandardCharsets.UTF_8)); + conn.connect(); + + if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) { + try (BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"))) { + StringBuilder response = new StringBuilder(); + String responseLine = null; + while ((responseLine = br.readLine()) != null) { + response.append(responseLine.trim()); + } + JsonNode responseBody = JsonUtils.toJsonNode(response.toString()); + String token = responseBody.get("access_token").asText(); + setToken(client, token); + } + } else { + throw new OperateException("Error "+conn.getResponseCode()+" obtaining access token : "+conn.getResponseMessage()); + } + } catch (IOException e) { + throw new OperateException(e); + } + } +}