diff --git a/docs/changelog/143408.yaml b/docs/changelog/143408.yaml new file mode 100644 index 0000000000000..1d0e67b36b007 --- /dev/null +++ b/docs/changelog/143408.yaml @@ -0,0 +1,7 @@ +area: SQL +issues: + - 143018 + - 143019 +pr: 143408 +summary: Fix SQL client parsing of array header values +type: bug diff --git a/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/RemoteFailure.java b/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/RemoteFailure.java index abf1228b5945c..6b16fb107f6ba 100644 --- a/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/RemoteFailure.java +++ b/x-pack/plugin/sql/sql-client/src/main/java/org/elasticsearch/xpack/sql/client/RemoteFailure.java @@ -269,10 +269,20 @@ private static Map parseHeaders(JsonParser parser) throws IOExce } String name = parser.getText(); token = parser.nextToken(); - if (token != JsonToken.VALUE_STRING) { + String value; + if (token == JsonToken.VALUE_STRING) { + value = parser.getText(); + } else if (token == JsonToken.START_ARRAY) { + List values = new ArrayList<>(); + while ((token = parser.nextToken()) != JsonToken.END_ARRAY) { + if (token == JsonToken.VALUE_STRING) { + values.add(parser.getText()); + } + } + value = String.join(", ", values); + } else { throw new IOException("expected header value but was [" + token + "][" + parser.getText() + "]"); } - String value = parser.getText(); headers.put(name, value); } diff --git a/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/RemoteFailureTests.java b/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/RemoteFailureTests.java index 258a738a076c8..d369eb9b0b961 100644 --- a/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/RemoteFailureTests.java +++ b/x-pack/plugin/sql/sql-client/src/test/java/org/elasticsearch/xpack/sql/client/RemoteFailureTests.java @@ -64,6 +64,18 @@ public void testParseMissingAuth() throws IOException { assertEquals(singletonMap("WWW-Authenticate", "Basic realm=\"security\", charset=\"UTF-8\""), failure.headers()); } + public void testParseMissingAuthMultipleSchemes() throws IOException { + RemoteFailure failure = parse("missing_auth_multiple_schemes.json"); + assertEquals("security_exception", failure.type()); + assertEquals( + "unable to authenticate with provided credentials and anonymous access is not allowed for this request", + failure.reason() + ); + assertThat(failure.remoteTrace(), containsString("AuthenticationService.authenticate")); + assertNull(failure.cause()); + assertEquals(singletonMap("WWW-Authenticate", "Basic realm=\"security\", charset=\"UTF-8\", ApiKey"), failure.headers()); + } + public void testNoError() { IOException e = expectThrows(IOException.class, () -> parse("no_error.json")); assertEquals( diff --git a/x-pack/plugin/sql/sql-client/src/test/resources/remote_failure/missing_auth_multiple_schemes.json b/x-pack/plugin/sql/sql-client/src/test/resources/remote_failure/missing_auth_multiple_schemes.json new file mode 100644 index 0000000000000..3d43a2d7c8af9 --- /dev/null +++ b/x-pack/plugin/sql/sql-client/src/test/resources/remote_failure/missing_auth_multiple_schemes.json @@ -0,0 +1,23 @@ +{ + "error" : { + "root_cause" : [ + { + "type" : "security_exception", + "reason" : "unable to authenticate with provided credentials and anonymous access is not allowed for this request", + "additional_unsuccessful_credentials" : "API key: Illegal base64 character 5f", + "header" : { + "WWW-Authenticate" : ["Basic realm=\"security\", charset=\"UTF-8\"", "ApiKey"] + }, + "stack_trace" : "ElasticsearchSecurityException[unable to authenticate]\n\tat org.elasticsearch.xpack.security.authc.AuthenticationService.authenticate(AuthenticationService.java:99)" + } + ], + "type" : "security_exception", + "reason" : "unable to authenticate with provided credentials and anonymous access is not allowed for this request", + "additional_unsuccessful_credentials" : "API key: Illegal base64 character 5f", + "header" : { + "WWW-Authenticate" : ["Basic realm=\"security\", charset=\"UTF-8\"", "ApiKey"] + }, + "stack_trace" : "ElasticsearchSecurityException[unable to authenticate]\n\tat org.elasticsearch.xpack.security.authc.AuthenticationService.authenticate(AuthenticationService.java:99)" + }, + "status" : 401 +}