Skip to content

Commit b700589

Browse files
fix: operate uses different csrf header for different versions (#161)
1 parent 4b07eba commit b700589

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

extension/java-client-operate/src/main/java/io/camunda/operate/auth/SimpleAuthentication.java

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,21 @@
99
import org.apache.hc.client5.http.entity.UrlEncodedFormEntity;
1010
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
1111
import org.apache.hc.client5.http.impl.classic.HttpClients;
12+
import org.apache.hc.core5.http.ClassicHttpResponse;
1213
import org.apache.hc.core5.http.Header;
1314
import org.apache.hc.core5.http.NameValuePair;
15+
import org.apache.hc.core5.http.ProtocolException;
1416
import org.apache.hc.core5.http.message.BasicNameValuePair;
1517
import org.slf4j.Logger;
1618
import org.slf4j.LoggerFactory;
1719

1820
public class SimpleAuthentication implements Authentication {
19-
private static final String CSRF_HEADER = "OPERATE-X-CSRF-TOKEN";
21+
private static final Set<String> CSRF_HEADER_CANDIDATES =
22+
Set.of("X-CSRF-TOKEN", "OPERATE-X-CSRF-TOKEN");
2023
private static final Logger LOG = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
2124

2225
private final SimpleCredential simpleCredential;
2326
private SimpleAuthToken token;
24-
private LocalDateTime sessionTimeout;
2527

2628
public SimpleAuthentication(SimpleCredential simpleCredential) {
2729
this.simpleCredential = simpleCredential;
@@ -39,9 +41,11 @@ private SimpleAuthToken retrieveToken() {
3941
"Unable to login, response code " + response.getCode());
4042
}
4143
String csrfTokenCandidate = null;
42-
Header csrfTokenHeader = response.getHeader(CSRF_HEADER);
44+
String csrfTokenHeaderName = null;
45+
Header csrfTokenHeader = findCsrfTokenHeader(response);
4346
if (csrfTokenHeader != null) {
4447
csrfTokenCandidate = csrfTokenHeader.getValue();
48+
csrfTokenHeaderName = csrfTokenHeader.getName();
4549
}
4650
Header[] cookieHeaders = response.getHeaders("Set-Cookie");
4751
String sessionCookie = null;
@@ -51,11 +55,18 @@ private SimpleAuthToken retrieveToken() {
5155
if (cookieHeader.getValue().startsWith(sessionCookieName)) {
5256
sessionCookie = cookieHeader.getValue();
5357
}
54-
if (cookieHeader.getValue().startsWith(CSRF_HEADER)) {
55-
csrfCookie = cookieHeader.getValue();
58+
for (String candidate : CSRF_HEADER_CANDIDATES) {
59+
if (cookieHeader.getValue().startsWith(candidate)) {
60+
csrfCookie = cookieHeader.getValue();
61+
}
5662
}
5763
}
58-
return new SimpleAuthToken(sessionCookie, csrfCookie, csrfTokenCandidate);
64+
return new SimpleAuthToken(
65+
sessionCookie,
66+
csrfCookie,
67+
csrfTokenCandidate,
68+
csrfTokenHeaderName,
69+
LocalDateTime.now().plus(simpleCredential.sessionTimeout()));
5970
});
6071
if (simpleAuthToken.sessionCookie() == null) {
6172
throw new RuntimeException(
@@ -67,13 +78,24 @@ private SimpleAuthToken retrieveToken() {
6778
if (simpleAuthToken.csrfCookie() == null) {
6879
LOG.info("No CSRF cookie found");
6980
}
70-
sessionTimeout = LocalDateTime.now().plus(simpleCredential.sessionTimeout());
7181
return simpleAuthToken;
7282
} catch (Exception e) {
7383
throw new RuntimeException("Unable to authenticate", e);
7484
}
7585
}
7686

87+
private Header findCsrfTokenHeader(ClassicHttpResponse response) throws ProtocolException {
88+
if (token != null) {
89+
return response.getHeader(token.csrfTokenHeaderName());
90+
}
91+
for (String candidate : CSRF_HEADER_CANDIDATES) {
92+
if (response.containsHeader(candidate)) {
93+
return response.getHeader(candidate);
94+
}
95+
}
96+
return null;
97+
}
98+
7799
private HttpPost buildRequest(SimpleCredential simpleCredential) {
78100
HttpPost httpPost = new HttpPost(simpleCredential.baseUrl().toString() + "/api/login");
79101
List<NameValuePair> params = new ArrayList<>();
@@ -85,12 +107,12 @@ private HttpPost buildRequest(SimpleCredential simpleCredential) {
85107

86108
@Override
87109
public Map<String, String> getTokenHeader() {
88-
if (token == null || sessionTimeout.isBefore(LocalDateTime.now())) {
110+
if (token == null || token.sessionTimeout().isBefore(LocalDateTime.now())) {
89111
token = retrieveToken();
90112
}
91113
Map<String, String> headers = new HashMap<>();
92114
if (token.csrfToken() != null) {
93-
headers.put(CSRF_HEADER, token.csrfToken());
115+
headers.put(token.csrfTokenHeaderName(), token.csrfToken());
94116
}
95117
headers.put(
96118
"Cookie",
@@ -105,5 +127,10 @@ public void resetToken() {
105127
token = null;
106128
}
107129

108-
private record SimpleAuthToken(String sessionCookie, String csrfCookie, String csrfToken) {}
130+
private record SimpleAuthToken(
131+
String sessionCookie,
132+
String csrfCookie,
133+
String csrfToken,
134+
String csrfTokenHeaderName,
135+
LocalDateTime sessionTimeout) {}
109136
}

0 commit comments

Comments
 (0)