Add unsecured /health endpoint, remove auth checks from isLeader (#5087)

* Add unsecured /health endpoint, remove auth checks from isLeader

* PR comments
This commit is contained in:
Jonathan Wei 2017-11-15 12:41:30 -08:00 committed by Himanshu
parent 7722401cb3
commit af44d1142b
9 changed files with 74 additions and 9 deletions

View File

@ -179,9 +179,11 @@ public class OverlordResource
return Response.ok(taskMaster.getCurrentLeader()).build();
}
/**
* This is an unsecured endpoint, defined as such in UNSECURED_PATHS in CliOverlord
*/
@GET
@Path("/isLeader")
@ResourceFilters(StateResourceFilter.class)
@Produces(MediaType.APPLICATION_JSON)
public Response isLeader()
{

View File

@ -38,16 +38,28 @@ import java.util.List;
/**
*/
@Path("/status")
@ResourceFilters(StateResourceFilter.class)
public class StatusResource
{
@GET
@ResourceFilters(StateResourceFilter.class)
@Produces(MediaType.APPLICATION_JSON)
public Status doGet()
{
return new Status(Initialization.getLoadedImplementations(DruidModule.class));
}
/**
* This is an unsecured endpoint, defined as such in UNSECURED_PATHS in the service initiailization files
* (e.g. CliOverlord, CoordinatorJettyServerInitializer)
*/
@GET
@Path("/health")
@Produces(MediaType.APPLICATION_JSON)
public boolean getHealth()
{
return true;
}
public static class Status
{
final String version;

View File

@ -41,7 +41,6 @@ import java.util.Map;
/**
*/
@Path("/druid/coordinator/v1")
@ResourceFilters(StateResourceFilter.class)
public class CoordinatorResource
{
private final DruidCoordinator coordinator;
@ -56,12 +55,16 @@ public class CoordinatorResource
@GET
@Path("/leader")
@ResourceFilters(StateResourceFilter.class)
@Produces(MediaType.APPLICATION_JSON)
public Response getLeader()
{
return Response.ok(coordinator.getCurrentLeader()).build();
}
/**
* This is an unsecured endpoint, defined as such in UNSECURED_PATHS in CoordinatorJettyServerInitializer
*/
@GET
@Path("/isLeader")
@Produces(MediaType.APPLICATION_JSON)
@ -78,6 +81,7 @@ public class CoordinatorResource
@GET
@Path("/loadstatus")
@ResourceFilters(StateResourceFilter.class)
@Produces(MediaType.APPLICATION_JSON)
public Response getLoadStatus(
@QueryParam("simple") String simple,
@ -96,6 +100,7 @@ public class CoordinatorResource
@GET
@Path("/loadqueue")
@ResourceFilters(StateResourceFilter.class)
@Produces(MediaType.APPLICATION_JSON)
public Response getLoadQueue(
@QueryParam("simple") String simple,

View File

@ -27,6 +27,10 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
/**
* Sets necessary request attributes for requests sent to endpoints that don't need authentication or
* authorization checks. This Filter is placed before all Authenticators in the filter chain.
*/
public class UnsecuredResourceFilter implements Filter
{
@Override
@ -40,6 +44,14 @@ public class UnsecuredResourceFilter implements Filter
ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain
) throws IOException, ServletException
{
// PreResponseAuthorizationCheckFilter checks that this attribute is set,
// but the value doesn't matter since we skip authorization checks for requests that go through this filter
servletRequest.setAttribute(
AuthConfig.DRUID_AUTHENTICATION_RESULT,
new AuthenticationResult(AuthConfig.ALLOW_ALL_NAME, AuthConfig.ALLOW_ALL_NAME, null)
);
// This request will not go to an Authorizer, so we need to set this for PreResponseAuthorizationCheckFilter
servletRequest.setAttribute(AuthConfig.DRUID_AUTHORIZATION_CHECKED, true);
filterChain.doFilter(servletRequest, servletResponse);
}

View File

@ -121,7 +121,9 @@ public class CliOverlord extends ServerRunnable
"/console.html",
"/old-console/*",
"/images/*",
"/js/*"
"/js/*",
"/druid/indexer/v1/isLeader",
"/status/health"
);
public CliOverlord()
@ -320,13 +322,15 @@ public class CliOverlord extends ServerRunnable
List<Authenticator> authenticators = null;
AuthenticationUtils.addSecuritySanityCheckFilter(root, jsonMapper);
// perform no-op authorization for these resources
AuthenticationUtils.addNoopAuthorizationFilters(root, UNSECURED_PATHS);
authenticators = authenticatorMapper.getAuthenticatorChain();
AuthenticationUtils.addAuthenticationFilterChain(root, authenticators);
JettyServerInitUtils.addExtensionFilters(root, injector);
// perform no-op authorization for these static resources
AuthenticationUtils.addNoopAuthorizationFilters(root, UNSECURED_PATHS);
// Check that requests were authorized before sending responses
AuthenticationUtils.addPreResponseAuthorizationCheckFilter(

View File

@ -62,7 +62,9 @@ class CoordinatorJettyServerInitializer implements JettyServerInitializer
"/fonts/*",
"/old-console/*",
"/coordinator/false",
"/overlord/false"
"/overlord/false",
"/status/health",
"/druid/coordinator/v1/isLeader"
);
private static Logger log = new Logger(CoordinatorJettyServerInitializer.class);
@ -112,13 +114,15 @@ class CoordinatorJettyServerInitializer implements JettyServerInitializer
List<Authenticator> authenticators = null;
AuthenticationUtils.addSecuritySanityCheckFilter(root, jsonMapper);
// perform no-op authorization for these resources
AuthenticationUtils.addNoopAuthorizationFilters(root, UNSECURED_PATHS);
authenticators = authenticatorMapper.getAuthenticatorChain();
AuthenticationUtils.addAuthenticationFilterChain(root, authenticators);
JettyServerInitUtils.addExtensionFilters(root, injector);
// perform no-op authorization for these static resources
AuthenticationUtils.addNoopAuthorizationFilters(root, UNSECURED_PATHS);
// Check that requests were authorized before sending responses
AuthenticationUtils.addPreResponseAuthorizationCheckFilter(

View File

@ -20,6 +20,7 @@
package io.druid.cli;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.servlet.GuiceFilter;
@ -47,6 +48,10 @@ class MiddleManagerJettyServerInitializer implements JettyServerInitializer
{
private static Logger log = new Logger(MiddleManagerJettyServerInitializer.class);
private static List<String> UNSECURED_PATHS = Lists.newArrayList(
"/status/health"
);
@Override
public void initialize(Server server, Injector injector)
{
@ -59,6 +64,10 @@ class MiddleManagerJettyServerInitializer implements JettyServerInitializer
List<Authenticator> authenticators = null;
AuthenticationUtils.addSecuritySanityCheckFilter(root, jsonMapper);
// perform no-op authorization for these resources
AuthenticationUtils.addNoopAuthorizationFilters(root, UNSECURED_PATHS);
authenticators = authenticatorMapper.getAuthenticatorChain();
AuthenticationUtils.addAuthenticationFilterChain(root, authenticators);

View File

@ -22,6 +22,7 @@ package io.druid.cli;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
@ -51,6 +52,9 @@ import java.util.Set;
public class QueryJettyServerInitializer implements JettyServerInitializer
{
private static final Logger log = new Logger(QueryJettyServerInitializer.class);
private static List<String> UNSECURED_PATHS = Lists.newArrayList(
"/status/health"
);
private final List<Handler> extensionHandlers;
@ -88,6 +92,10 @@ public class QueryJettyServerInitializer implements JettyServerInitializer
List<Authenticator> authenticators = null;
AuthenticationUtils.addSecuritySanityCheckFilter(root, jsonMapper);
// perform no-op authorization for these resources
AuthenticationUtils.addNoopAuthorizationFilters(root, UNSECURED_PATHS);
authenticators = authenticatorMapper.getAuthenticatorChain();
AuthenticationUtils.addAuthenticationFilterChain(root, authenticators);

View File

@ -20,6 +20,7 @@
package io.druid.cli;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
@ -50,6 +51,10 @@ public class RouterJettyServerInitializer implements JettyServerInitializer
{
private static Logger log = new Logger(RouterJettyServerInitializer.class);
private static List<String> UNSECURED_PATHS = Lists.newArrayList(
"/status/health"
);
private final AsyncQueryForwardingServlet asyncQueryForwardingServlet;
private final DruidHttpClientConfig httpClientConfig;
@ -88,6 +93,10 @@ public class RouterJettyServerInitializer implements JettyServerInitializer
List<Authenticator> authenticators = null;
AuthenticationUtils.addSecuritySanityCheckFilter(root, jsonMapper);
// perform no-op authorization for these resources
AuthenticationUtils.addNoopAuthorizationFilters(root, UNSECURED_PATHS);
authenticators = authenticatorMapper.getAuthenticatorChain();
AuthenticationUtils.addAuthenticationFilterChain(root, authenticators);