Using RestHandlers for custom Authentication Plugin

Hi,

I am trying to write simple custom authentication plugin for elasticsearch v5.4.1. In previous versions before 5.4.2, it could be done with Restfilters. But now they are not present. Somewhere i read that use RestHandlers for the same. However , I am not able to get code executed inside my custom handler.

What i am trying to achieve is that i will get a header having authentication information in my rest request. Will validate that information using external services inside my custom handler and if authenticated, execute the call else throw excecption.

My custom handler looks like below:-

public class AuthenticationHandler implements RestHandler {

public AuthenticationHandler(Settings settings, RestController controller) {
	super();
	controller.registerHandler(Method.GET, "/shakespeare", this);
}

@Override
public void handleRequest(RestRequest request, RestChannel channel, NodeClient client) throws IOException {
	System.out.println("AuthenticationHandler is running");
	List<String> header = request.getHeaders().get("auth");
	if (authenticate(header)) {
		// execute the actual request
	} else
		throw new RuntimeException("authentication failed");
}

private boolean authenticate(List<String> header) {
	// TODO Use external services to authenticate further
	return true;
}

}

My plugin class looks like below:-

public class ESPlugin extends Plugin implements ActionPlugin {

public List<RestHandler> getRestHandlers(Settings settings, RestController restController,
		ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter,
		IndexNameExpressionResolver indexNameExpressionResolver, Supplier<DiscoveryNodes> nodesInCluster) {
	return Arrays.asList(new AuthenticationHandler(settings, restController));
}

}

However, my custom code is not being executed.
Can someone help me out in this regards?

Hey,

the correct place would be to filter the actions and not the REST requests. Check out the ActionPlugin class for more info.

--Alex

Thanks for the reply. I was able to create a basic plugin for the same in the following way..
My plugin class:
public class ESPlugin extends Plugin implements ActionPlugin {

public List<RestHandler> getRestHandlers(Settings settings, RestController restController,
		ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter,
		IndexNameExpressionResolver indexNameExpressionResolver, Supplier<DiscoveryNodes> nodesInCluster) {
	return Arrays.asList(new AuthenticationHandler(settings, restController));
}

@Override
public List<Class<? extends RestHandler>> getRestHandlers() {
	return Arrays.asList(AuthenticationHandler.class);
}

}

My Handler:
public class AuthenticationHandler extends BaseRestHandler {

@Inject
public AuthenticationHandler(Settings settings, RestController controller) {
	super(settings);
	controller.registerFilter(new AuthenticationFilter());
}

@Override
protected RestChannelConsumer prepareRequest(RestRequest restRequest, NodeClient client) throws IOException {
	return channel -> {
		XContentBuilder builder = channel.newBuilder();
		builder.startObject();
		builder.endObject();
		channel.sendResponse(new BytesRestResponse(RestStatus.OK, builder));
	};
}

}

My authentication filter that does the actual work:
public class AuthenticationFilter extends RestFilter {

@Override
public void process(RestRequest request, RestChannel channel, NodeClient client, RestFilterChain filterChain)
		throws Exception {
	try {
		if (authenticate(request)) {
			filterChain.continueProcessing(request, channel, client);
		} else {
			final ElasticsearchException exception = new ElasticsearchException("Did not find authentication");
			XContentBuilder s = XContentFactory.jsonBuilder().startObject().field(request.uri())
					.field(request.rawPath()).endObject();
			channel.sendResponse(new BytesRestResponse(channel, RestStatus.FORBIDDEN, exception));
		}
	} catch (Exception e) {
		channel.sendResponse(new BytesRestResponse(channel, RestStatus.FORBIDDEN, e));
		return;
	}

}

}

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.