How to create authorization header for Log4j2 HTTP appender?

651 Views Asked by At

Is there a proper way to create an authorization header that can regenerated every time you POST using the HTTP appender?

Background: The authorization header needs to be calculated every time we POST data to the api. This auth is the only method that is accepted via the API. It consists of a signature,ID,and the epoch time. It wont be able to be set as an environment variable because the api will not accept auth headers older than X minutes.

My current method is this: I am trying to use the Scripts in the configuration of the log4j2 to return a value that will be used in the HTTP appender

https://logging.apache.org/log4j/2.x/manual/configuration.html#Scripts

Here is my log4j2http.xml

 <?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="MyApp">
  <Scripts>
    <Script name="selector" language="groovy">
      <![CDATA[

      import org.apache.commons.codec.binary.Hex
      import javax.crypto.Mac
      import javax.crypto.spec.SecretKeySpec
      import java.security.MessageDigest
      def id="XXXXXXXXXXXXXx"
      Long epoch_time = System.currentTimeMillis()
      Mac hmac = Mac.getInstance("HmacSHA256")
      hmac.init(new SecretKeySpec(key.getBytes(), "HmacSHA256"))
      def signature = Hex.encodeHexString(hmac.doFinal("GET${epoch_time}${path}".getBytes())).bytes.encodeBase64()
  
      return "${id}:${signature}:${epoch_time}"
            ]]>
    </Script>
  </Scripts>
  <Appenders>
    <Http name="Http" url="https://XXX/rest/log/ingest" method="POST">
      
      <KeyValuePair key="_Id:" value="{Id:&quot;588&quot;}" />
      <Property name="Authorization" value="${result}" />
      <Property name="Accept" value="application/json" />
      <JsonLayout properties="true" />
    </Http>

  </Appenders>
  <Loggers>
    <Root level="trace">
      <AppenderRef ref="Http" />
    </Root>
  </Loggers>
</Configuration>

App:

package App;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import java.io.*;

public class App {

    public static void main(String[] args) {

        System.setProperty("log4j2.Script.enableLanguages","groovy");
        System.setProperty("log4j2.debug","false");
        
        Logger logger = LogManager.getLogger("App");
        LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
        
        File file = new File("log4j2http.xml"); 
        context.setConfigLocation(file.toURI());     
        
        logger.debug("Debug log");

    }
}

I'm not getting an error , just an empty ${result}. It is making me think that importing the groovy libraries is not working correctly or the script itself has errors. With debug on, it doesn't seem that I can see if the script is executing correctly. This likely doesn't seem to be the correct method nor do I know if this is possible.

2022-10-09 00:58:39,198 main DEBUG Installed 2 script engines
2022-10-09 00:58:39,251 main DEBUG Groovy Scripting Engine version: 2.0, language: Groovy, threading: MULTITHREADED, compile: true, names: [groovy, Groovy], factory class: org.codehaus.groovy.jsr223.GroovyScriptEngineFactory
2022-10-09 00:58:39,252 main DEBUG PluginManager 'Core' found 127 plugins
2022-10-09 00:58:39,252 main DEBUG PluginManager 'Level' found 0 plugins
2022-10-09 00:58:39,257 main DEBUG PluginManager 'Lookup' found 16 plugins
2022-10-09 00:58:39,259 main DEBUG Building Plugin[name=Script, class=org.apache.logging.log4j.core.script.Script].
2022-10-09 00:58:39,278 main DEBUG PluginManager 'TypeConverter' found 26 plugins
2022-10-09 00:58:39,292 main DEBUG createScript(name="selector", language="groovy", scriptText=".................")
2022-10-09 00:58:39,292 main DEBUG Building Plugin[name=scripts, class=org.apache.logging.log4j.core.config.ScriptsPlugin].
2022-10-09 00:58:39,295 main DEBUG createScripts(={selector})
2022-10-09 00:58:39,297 main DEBUG Script selector is compilable
2022-10-09 00:58:40,383 main DEBUG Building Plugin[name=KeyValuePair, class=org.apache.logging.log4j.core.util.KeyValuePair].
2022-10-09 00:58:40,388 main DEBUG KeyValuePair$Builder(key="_Id:", value="{Id:"588"}")
2022-10-09 00:58:40,389 main DEBUG Building Plugin[name=property, class=org.apache.logging.log4j.core.config.Property].
2022-10-09 00:58:40,389 main DEBUG createProperty(name="Authorization", value="${result}", value="null")
0

There are 0 best solutions below