Skip to content

Commit

Permalink
check jwt token expiration and refresh token if necessary
Browse files Browse the repository at this point in the history
  • Loading branch information
chDame committed Aug 3, 2022
1 parent 6d17abf commit 7b30a45
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 9 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ You can import it to your maven or gradle project as a dependency
<dependency>
<groupId>io.camunda</groupId>
<artifactId>camunda-operate-client-java</artifactId>
<version>1.1.0</version>
<version>1.2.0</version>
</dependency>
```

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
}

group = 'io.camunda'
version = '1.1.0'
version = '1.2.0'
sourceCompatibility = '8'

repositories {
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/io/camunda/operate/CamundaOperateClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@

public class CamundaOperateClient {

private AuthInterface authentication;

private String operateUrl;

private Header authHeader;

private int tokenExpiration;

public ProcessDefinition getProcessDefinition(Long key) throws OperateException {
return get(key, ProcessDefinition.class);
Expand Down Expand Up @@ -161,6 +165,7 @@ private <T> T get(Long key, Class<T> resultType) throws OperateException {
}

protected String executeQuery(ClassicHttpRequest httpRequest) throws OperateException {
reconnectEventually();
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
try (CloseableHttpResponse response = httpClient.execute(httpRequest)) {
return new String(Java8Utils.readAllBytes(response.getEntity().getContent()), StandardCharsets.UTF_8);
Expand All @@ -186,6 +191,16 @@ public void setAuthHeader(Header authHeader) {
this.authHeader = authHeader;
}

public void setTokenExpiration(int tokenExpiration) {
this.tokenExpiration = tokenExpiration;
}

private void reconnectEventually() throws OperateException {
if (this.tokenExpiration>0 && this.tokenExpiration<(System.currentTimeMillis()/1000-30)) {
authentication.authenticate(this);
}
}

public static class Builder {

private AuthInterface authentication;
Expand Down Expand Up @@ -220,6 +235,7 @@ public CamundaOperateClient build() throws OperateException {
} else {
client = new CamundaOperateClient();
}
client.authentication = authentication;
client.operateUrl = operateUrl;
authentication.authenticate(client);
return client;
Expand Down
41 changes: 41 additions & 0 deletions src/main/java/io/camunda/operate/auth/JwtAuthentication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package io.camunda.operate.auth;

import java.util.Base64;

import org.apache.hc.core5.http.message.BasicHeader;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import io.camunda.operate.CamundaOperateClient;
import io.camunda.operate.exception.OperateException;

public abstract class JwtAuthentication implements AuthInterface {

private static final ObjectMapper MAPPER = new ObjectMapper();
private static final Base64.Decoder DECODER = Base64.getUrlDecoder();

public int getExpiration(String token) throws OperateException {
try {
String[] chunks = token.split("\\.");


String payload = new String(DECODER.decode(chunks[1]));
JsonNode jsonPayload = MAPPER.readValue(payload, JsonNode.class);
JsonNode exp = jsonPayload.get("exp");
if (exp==null) {
return 0;
} else {
return exp.asInt();
}
} catch (JsonProcessingException e) {
throw new OperateException("Token is not readable", e);
}
}

public void setToken(CamundaOperateClient client, String token) throws OperateException {
client.setAuthHeader(new BasicHeader("Authorization", "Bearer " + token));
client.setTokenExpiration(getExpiration(token));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;

import org.apache.hc.core5.http.message.BasicHeader;

import com.fasterxml.jackson.databind.JsonNode;

import io.camunda.operate.CamundaOperateClient;
import io.camunda.operate.exception.OperateException;
import io.camunda.operate.util.JsonUtils;

public class LocalIdentityAuthentication implements AuthInterface {
public class LocalIdentityAuthentication extends JwtAuthentication {

private String clientId;
private String clientSecret;
Expand Down Expand Up @@ -83,7 +81,7 @@ public void authenticate(CamundaOperateClient client) throws OperateException {
}
JsonNode responseBody = JsonUtils.toJsonNode(response.toString());
String token = responseBody.get("access_token").asText();
client.setAuthHeader(new BasicHeader("Authorization", "Bearer " + token));
setToken(client, token);
}
} else {
throw new OperateException("Error "+conn.getResponseCode()+" obtaining access token : "+conn.getResponseMessage());
Expand Down
5 changes: 2 additions & 3 deletions src/main/java/io/camunda/operate/auth/SaasAuthentication.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.core5.http.io.entity.StringEntity;
import org.apache.hc.core5.http.message.BasicHeader;

import com.fasterxml.jackson.databind.JsonNode;

import io.camunda.operate.CamundaOperateClient;
import io.camunda.operate.exception.OperateException;
import io.camunda.operate.util.JsonUtils;

public class SaasAuthentication implements AuthInterface {
public class SaasAuthentication extends JwtAuthentication {

private String clientId;
private String clientSecret;
Expand All @@ -40,7 +39,7 @@ public void authenticate(CamundaOperateClient client) throws OperateException {
JsonNode responseBody = JsonUtils.toJsonNode(response.getEntity().getContent());
String token = responseBody.get("access_token").asText();

client.setAuthHeader(new BasicHeader("Authorization", "Bearer " + token));
setToken(client, token);
}
} catch (IOException e) {
throw new OperateException(e);
Expand Down

0 comments on commit 7b30a45

Please sign in to comment.