Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use API key authentication to connect to Elasticsearch #178

Open
smriti2901 opened this issue Oct 23, 2023 · 1 comment
Open

Comments

@smriti2901
Copy link

smriti2901 commented Oct 23, 2023

Currently we use Basic Authentication to create document logs in elastic which works fine with NLog.Targets.ElasticSearch v7.7.0. On switching to API Key authentication I keep getting Unauthorized error on authentication. Our ElasticSearch is on version 8.7.0.

Here is the exception stack trace
Exception: Elasticsearch.Net.ElasticsearchClientException: Could not authenticate with the specified node. Try verifying your credentials or check your Shield configuration. Call: Status code 401 from: POST /_bulk ---> Elasticsearch.Net.PipelineException: Could not authenticate with the specified node. Try verifying your credentials or check your Shield configuration. ---> System.Net.WebException: The remote server returned an error: (401) Unauthorized. at System.Net.HttpWebRequest.GetResponse() at Elasticsearch.Net.HttpWebRequestConnection.Request[TResponse](RequestData requestData) --- End of inner exception stack trace --- at Elasticsearch.Net.RequestPipeline.ThrowBadAuthPipelineExceptionWhenNeeded(IApiCallDetails details, IElasticsearchResponse response) at Elasticsearch.Net.RequestPipeline.CallElasticsearch[TResponse](RequestData requestData) at Elasticsearch.Net.Transport1.Request[TResponse](HttpMethod method, String path, PostData data, IRequestParameters requestParameters)`

The API Key is working with curl request to fetch the document based on elastic uri and the index. I am passing the same API Key in the Authorization header. So permission shouldn't be the problem. Here is the API Key information and you can see privileges are set correctly.

{ "api_keys": [ { "username": "*****", "realm": "cloud-saml", "name": "*****", "creation": 1693470140150, "invalidated": false, "role_descriptors": { "appuser": { "applications": [], "transient_metadata": { "enabled": true }, "run_as": [], "cluster": [], "indices": [ { "privileges": [ "write", "create_index", "create_doc", "create", "all" ], "allow_restricted_indices": false, "names": [ "logs-<index1>-default-*", "logs-<index2>-*" ] } ], "metadata": {} } }, "id": "APIKEYID", "metadata": {} } ] }

Here is my NLog.Config

<?xml version="1.0" encoding="utf-8"?>

<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	  xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
      autoReload="true"
      throwExceptions="false"
      internalLogLevel="Error" internalLogFile="${basedir}/logs/error.log">

	<variable name="defaultLayout" value="${longdate} | ${level:uppercase=true} | ${logger} | ${message}${onexception:${newline}${exception:format=tostring}}"/>
	<extensions>
		<add assembly="NLog.Web" />
		<add assembly="NLog.Targets.ElasticSearch" />
		<add assembly="Elastic.Apm.NLog"/>
		<add assembly="Elastic.CommonSchema.NLog"/>
	</extensions>
	<targets>
		<target name="elastic" xsi:type="BufferingWrapper" flushTimeout="5000">
			<target xsi:type="ElasticSearch"
					name="elastic"
					enableJsonLayout="true"
					opCodeCreate="true"
					includeDefaultFields="true"
					includeAllProperties="true"
					documentType="">
				<layout xsi:type="EcsLayout">
					<metadata name="data_stream.dataset" layout="${appsetting:Log.DataStream.Dataset}" />
					<metadata name="application.title" layout="${appsetting:Log.Application.Title}" />
				</layout>
			</target>
		</target>
	</targets>

	<rules>
		<logger name="*" minlevel="Trace" writeTo="elastic" />
	</rules>
</nlog>

And my helper class to initialize the ElasticSearchTarget

public static class ElasticSearchTargetSetup
    {
        public static bool SetupElasticTarget()
        {
            bool isElasticActive = false;

            var elasticTargetWrapper = LogManager.LogFactory.Configuration.AllTargets.SingleOrDefault(x => x is BufferingTargetWrapper) as BufferingTargetWrapper;

            if (elasticTargetWrapper != null && elasticTargetWrapper.WrappedTarget is ElasticSearchTarget)
            {
                var elasticTarget = elasticTargetWrapper.WrappedTarget as ElasticSearchTarget;
                elasticTarget.Index = ConfigurationManager.AppSettings["Log.Elastic.Index"];
                elasticTarget.CloudId = ConfigurationManager.AppSettings["Log.Elastic.CloudId"];
                elasticTarget.Uri = ConfigurationManager.AppSettings["Log.Elastic.Url"];
                elasticTarget.ApiKeyId = ConfigurationManager.AppSettings["Log.Elastic.ApiKeyId"];
                elasticTarget.ApiKey = ConfigurationManager.AppSettings["Log.Elastic.ApiKey"];
            }            

            return isElasticActive;
        }
    }

Here is my web.config to read appsettings

<appSettings>
	<add key="Log.Application.Title" value="My App 1" />
	<add key="Log.DataStream.Dataset" value="my data stream" />
	<add key="Log.Elastic.CloudId" value="my-cluster:<Base64string>" />
	<add key="Log.Elastic.Index" value="logs-<index1>-default" />
	<add key="Log.Elastic.Url" value="https://my-elastic-cloud:9243" />
	<add key="Log.Elastic.ApiKeyId" value="APIKEYID"/>
	<add key="Log.Elastic.ApiKey" value="APIKEY"/>
</appSettings>

Has anyone faced this issue or were able to use the API Key authentication successfully with NLog.Targets.ElasticSearch 7.7.0?

@snakefoot
Copy link
Collaborator

Notice that ElasticSearch have now released their own official NLog Target for ElasticSearch:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants