Skip to content

Commit

Permalink
[Backport 2.x] Add early rejection from RestHandler for unauthorized …
Browse files Browse the repository at this point in the history
…requests (opensearch-project#3418) (opensearch-project#3496)

Backport f7c47af from opensearch-project#3495

---------

Signed-off-by: Peter Nied <petern@amazon.com>
Co-authored-by: Peter Nied <petern@amazon.com>
  • Loading branch information
opensearch-trigger-bot[bot] and peternied committed Oct 9, 2023
1 parent 8cc4f00 commit 8b74d6f
Show file tree
Hide file tree
Showing 7 changed files with 37 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ private Long runResourceTest(
CompletableFuture<Void> statPrinter = statsPrinter ? CompletableFuture.runAsync(() -> {
while (true) {
printStats();
System.out.println(" & Succesful completions: " + getCount.get());
System.err.println(" & Succesful completions: " + getCount.get());
try {
Thread.sleep(500);
} catch (Exception e) {
Expand All @@ -159,7 +159,7 @@ private Long runResourceTest(

if (statsPrinter) {
printStats();
System.out.println(" & Succesful completions: " + getCount.get());
System.err.println(" & Succesful completions: " + getCount.get());
}
return getCount.get();
}
Expand Down Expand Up @@ -207,7 +207,7 @@ private byte[] createCompressedRequestBody(final RequestBodySize size) {
gzipOutputStream.finish();

final byte[] compressedRequestBody = byteArrayOutputStream.toByteArray();
System.out.println(
System.err.println(
"^^^"
+ String.format(
"Original size was %,d bytes, compressed to %,d bytes, ratio %,.2f",
Expand All @@ -223,7 +223,7 @@ private byte[] createCompressedRequestBody(final RequestBodySize size) {
}

private void printStats() {
System.out.println("** Stats ");
System.err.println("** Stats ");
printMemory();
printMemoryPools();
printGCPools();
Expand All @@ -236,21 +236,21 @@ private void printMemory() {
final long freeMemory = runtime.freeMemory(); // Amount of free memory
final long usedMemory = totalMemory - freeMemory; // Amount of used memory

System.out.println(" Memory Total: " + totalMemory + " Free:" + freeMemory + " Used:" + usedMemory);
System.err.println(" Memory Total: " + totalMemory + " Free:" + freeMemory + " Used:" + usedMemory);
}

private void printMemoryPools() {
List<MemoryPoolMXBean> memoryPools = ManagementFactory.getMemoryPoolMXBeans();
for (MemoryPoolMXBean memoryPool : memoryPools) {
MemoryUsage usage = memoryPool.getUsage();
System.out.println(" " + memoryPool.getName() + " USED: " + usage.getUsed() + " MAX: " + usage.getMax());
System.err.println(" " + memoryPool.getName() + " USED: " + usage.getUsed() + " MAX: " + usage.getMax());
}
}

private void printGCPools() {
List<GarbageCollectorMXBean> garbageCollectors = ManagementFactory.getGarbageCollectorMXBeans();
for (GarbageCollectorMXBean garbageCollector : garbageCollectors) {
System.out.println(" " + garbageCollector.getName() + " COLLECTION TIME: " + garbageCollector.getCollectionTime());
System.err.println(" " + garbageCollector.getName() + " COLLECTION TIME: " + garbageCollector.getCollectionTime());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ private JsonNode getJsonNodeAt(String jsonPointer) {
try {
return toJsonNode().at(jsonPointer);
} catch (IOException e) {
throw new IllegalArgumentException("Cound not convert response body to JSON node ", e);
throw new IllegalArgumentException("Cound not convert response body to JSON node '" + getBody() + "'", e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ private Optional<SecurityResponse> handleLowLevel(RestRequest restRequest) throw
return Optional.of(new SecurityResponse(HttpStatus.SC_OK, SecurityResponse.CONTENT_TYPE_APP_JSON, responseBodyString));
} catch (JsonProcessingException e) {
log.warn("Error while parsing JSON for /_opendistro/_security/api/authtoken", e);
return Optional.of(new SecurityResponse(HttpStatus.SC_BAD_REQUEST, null, "JSON could not be parsed"));
return Optional.of(new SecurityResponse(HttpStatus.SC_BAD_REQUEST, new Exception("JSON could not be parsed")));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ public boolean authenticate(final SecurityRequestChannel request) {
log.debug("Rejecting REST request because of blocked address: {}", request.getRemoteAddress().orElse(null));
}

request.queueForSending(new SecurityResponse(SC_UNAUTHORIZED, null, "Authentication finally failed"));
request.queueForSending(new SecurityResponse(SC_UNAUTHORIZED, new Exception("Authentication finally failed")));
return false;
}

Expand All @@ -226,7 +226,7 @@ public boolean authenticate(final SecurityRequestChannel request) {

if (!isInitialized()) {
log.error("Not yet initialized (you may need to run securityadmin)");
request.queueForSending(new SecurityResponse(SC_SERVICE_UNAVAILABLE, null, "OpenSearch Security not initialized."));
request.queueForSending(new SecurityResponse(SC_SERVICE_UNAVAILABLE, new Exception("OpenSearch Security not initialized.")));
return false;
}

Expand Down
22 changes: 22 additions & 0 deletions src/main/java/org/opensearch/security/filter/SecurityResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@

package org.opensearch.security.filter;

import java.io.IOException;
import java.util.Map;

import org.apache.http.HttpHeaders;
import org.opensearch.common.xcontent.XContentFactory;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.rest.BytesRestResponse;
import org.opensearch.rest.RestResponse;
Expand All @@ -26,6 +28,12 @@ public class SecurityResponse {
private final Map<String, String> headers;
private final String body;

public SecurityResponse(final int status, final Exception e) {
this.status = status;
this.headers = CONTENT_TYPE_APP_JSON;
this.body = generateFailureMessage(e);
}

public SecurityResponse(final int status, final Map<String, String> headers, final String body) {
this.status = status;
this.headers = headers;
Expand All @@ -52,4 +60,18 @@ public RestResponse asRestResponse() {
return restResponse;
}

protected String generateFailureMessage(final Exception e) {
try {
return XContentFactory.jsonBuilder()
.startObject()
.startObject("error")
.field("status", "error")
.field("reason", e.getMessage())
.endObject()
.endObject()
.toString();
} catch (final IOException ioe) {
throw new RuntimeException(ioe);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ public void checkAndAuthenticateRequest(SecurityRequestChannel requestChannel) t
log.error(exception.toString());
auditLog.logBadHeaders(requestChannel);

requestChannel.queueForSending(new SecurityResponse(HttpStatus.SC_FORBIDDEN, null, exception.toString()));
requestChannel.queueForSending(new SecurityResponse(HttpStatus.SC_FORBIDDEN, exception));
return;
}

Expand All @@ -256,7 +256,7 @@ public void checkAndAuthenticateRequest(SecurityRequestChannel requestChannel) t
log.error(exception.toString());
auditLog.logBadHeaders(requestChannel);

requestChannel.queueForSending(new SecurityResponse(HttpStatus.SC_FORBIDDEN, null, exception.toString()));
requestChannel.queueForSending(new SecurityResponse(HttpStatus.SC_FORBIDDEN, exception));
return;
}

Expand All @@ -276,7 +276,7 @@ public void checkAndAuthenticateRequest(SecurityRequestChannel requestChannel) t
} catch (SSLPeerUnverifiedException e) {
log.error("No ssl info", e);
auditLog.logSSLException(requestChannel, e);
requestChannel.queueForSending(new SecurityResponse(HttpStatus.SC_FORBIDDEN, null, null));
requestChannel.queueForSending(new SecurityResponse(HttpStatus.SC_FORBIDDEN, new Exception("No ssl info")));
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public void channelRead0(ChannelHandlerContext ctx, DefaultHttpRequest msg) thro
ctx.channel().attr(IS_AUTHENTICATED).set(Boolean.TRUE);
}
} catch (final OpenSearchSecurityException e) {
final SecurityResponse earlyResponse = new SecurityResponse(ExceptionsHelper.status(e).getStatus(), null, e.getMessage());
final SecurityResponse earlyResponse = new SecurityResponse(ExceptionsHelper.status(e).getStatus(), e);
ctx.channel().attr(EARLY_RESPONSE).set(earlyResponse);
} catch (final SecurityRequestChannelUnsupported srcu) {
// Use defaults for unsupported channels
Expand Down

0 comments on commit 8b74d6f

Please sign in to comment.