Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,12 @@ public AuthCredentials extractCredentials(final SecurityRequest request, final T
return authCredentials;
}

public static boolean isAuthTokenEndpoint(final SecurityRequest request) {
Matcher matcher = PATTERN_PATH_PREFIX.matcher(request.path());
final String suffix = matcher.matches() ? matcher.group(2) : null;
return API_AUTHTOKEN_SUFFIX.equals(suffix);
}

@Override
public String getType() {
return "saml";
Expand All @@ -181,10 +187,7 @@ public String getType() {
@Override
public Optional<SecurityResponse> reRequestAuthentication(final SecurityRequest request, final AuthCredentials authCredentials) {
try {
Matcher matcher = PATTERN_PATH_PREFIX.matcher(request.path());
final String suffix = matcher.matches() ? matcher.group(2) : null;

if (API_AUTHTOKEN_SUFFIX.equals(suffix)) {
if (isAuthTokenEndpoint(request)) {
// Verficiation of SAML ASC endpoint only works with RestRequests
if (!(request instanceof OpenSearchRequest)) {
throw new SecurityRequestChannelUnsupported(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@
import org.opensearch.security.privileges.RestLayerPrivilegesEvaluator;
import org.opensearch.security.resolver.IndexResolverReplacer;
import org.opensearch.security.rest.DashboardsInfoAction;
import org.opensearch.security.rest.FailOnAnonymousAction;
import org.opensearch.security.rest.SecurityConfigUpdateAction;
import org.opensearch.security.rest.SecurityHealthAction;
import org.opensearch.security.rest.SecurityInfoAction;
Expand Down Expand Up @@ -562,6 +563,7 @@ public List<RestHandler> getRestHandlers(
handlers.add(
new SecurityInfoAction(settings, restController, Objects.requireNonNull(evaluator), Objects.requireNonNull(threadPool))
);
handlers.add(new FailOnAnonymousAction());
handlers.add(new SecurityHealthAction(settings, restController, Objects.requireNonNull(backendRegistry)));
handlers.add(
new DashboardsInfoAction(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@
import static org.apache.http.HttpStatus.SC_FORBIDDEN;
import static org.apache.http.HttpStatus.SC_SERVICE_UNAVAILABLE;
import static org.apache.http.HttpStatus.SC_UNAUTHORIZED;
import static org.opensearch.security.rest.FailOnAnonymousAction.isFailOnAnonymousEndpoint;
import static com.amazon.dlic.auth.http.saml.HTTPSamlAuthenticator.isAuthTokenEndpoint;

public class BackendRegistry {

Expand Down Expand Up @@ -286,7 +288,7 @@ public boolean authenticate(final SecurityRequestChannel request) {

if (ac == null) {
// no credentials found in request
if (anonymousAuthEnabled) {
if (anonymousAuthEnabled && !(isFailOnAnonymousEndpoint(request) || isAuthTokenEndpoint(request))) {
continue;
}

Expand Down Expand Up @@ -386,7 +388,7 @@ public boolean authenticate(final SecurityRequestChannel request) {
log.debug("User still not authenticated after checking {} auth domains", restAuthDomains.size());
}

if (authCredentials == null && anonymousAuthEnabled) {
if (authCredentials == null && anonymousAuthEnabled && !(isFailOnAnonymousEndpoint(request) || isAuthTokenEndpoint(request))) {
final String tenant = resolveTenantFrom(request);
User anonymousUser = new User(User.ANONYMOUS.getName(), new HashSet<String>(User.ANONYMOUS.getRoles()), null);
anonymousUser.setRequestedTenant(tenant);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.security.rest;

import java.io.IOException;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.google.common.collect.ImmutableList;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import org.opensearch.client.node.NodeClient;
import org.opensearch.core.rest.RestStatus;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.rest.BaseRestHandler;
import org.opensearch.rest.BytesRestResponse;
import org.opensearch.rest.RestChannel;
import org.opensearch.rest.RestRequest;
import org.opensearch.security.filter.SecurityRequest;

import static org.opensearch.rest.RestRequest.Method.GET;
import static org.opensearch.security.OpenSearchSecurityPlugin.LEGACY_OPENDISTRO_PREFIX;
import static org.opensearch.security.OpenSearchSecurityPlugin.PLUGINS_PREFIX;
import static org.opensearch.security.dlic.rest.support.Utils.addRoutesPrefix;

public class FailOnAnonymousAction extends BaseRestHandler {
private static final List<Route> routes = addRoutesPrefix(
ImmutableList.of(new Route(GET, "/failonanonymous")),
"/_opendistro/_security",
"/_plugins/_security"
);

private static final String FAILONANONYMOUS_SUFFIX = "failonanonymous";
private static final String REGEX_PATH_PREFIX = "/(" + LEGACY_OPENDISTRO_PREFIX + "|" + PLUGINS_PREFIX + ")/" + "(.*)";
private static final Pattern PATTERN_PATH_PREFIX = Pattern.compile(REGEX_PATH_PREFIX);

public static boolean isFailOnAnonymousEndpoint(final SecurityRequest request) {
Matcher matcher = PATTERN_PATH_PREFIX.matcher(request.path());
final String suffix = matcher.matches() ? matcher.group(2) : null;
return FAILONANONYMOUS_SUFFIX.equals(suffix);
}

private final Logger log = LogManager.getLogger(this.getClass());

public FailOnAnonymousAction() {
super();
}

@Override
public List<Route> routes() {
return routes;
}

@Override
protected RestChannelConsumer prepareRequest(RestRequest request, NodeClient client) throws IOException {
return new RestChannelConsumer() {

@Override
public void accept(RestChannel channel) throws Exception {
XContentBuilder builder = channel.newBuilder(); // NOSONAR
BytesRestResponse response = null;

builder.startObject();
builder.field("success", "true");

builder.endObject();

response = new BytesRestResponse(RestStatus.OK, builder);

channel.sendResponse(response);
}
};
}

@Override
public String getName() {
return "OpenSearch Security Fail on Anonymous Action";
}
}