Index: /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUAbstractRequest.java
===================================================================
--- /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUAbstractRequest.java	(revision 7265)
+++ /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUAbstractRequest.java	(revision 7266)
@@ -81,9 +81,4 @@
 
 
-    enum SRUOperation {
-        EXPLAIN, SCAN, SEARCH_RETRIEVE
-    } // enum SRUOperation
-
-
     protected static class URIHelper {
         private final URIBuilder uriBuilder;
@@ -477,5 +472,5 @@
      * @return a operation constant for this request
      */
-    abstract SRUOperation getOperation();
+    public abstract SRUOperation getOperation();
 
 
Index: /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUClientConfig.java
===================================================================
--- /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUClientConfig.java	(revision 7265)
+++ /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUClientConfig.java	(revision 7266)
@@ -39,4 +39,5 @@
     private final CloseableHttpClient httpClient;
     private final HttpClientContext httpContext;
+    private final SRURequestAuthenticator requestAuthenticator;
     private final int threadCount;
     private final List<SRURecordDataParser> recordParsers;
@@ -83,4 +84,14 @@
     public CloseableHttpClient getCustomizedHttpClient() {
         return httpClient;
+    }
+
+
+    /**
+     * Get the request authenticator
+     * 
+     * @return the configured request authenticator or <code>null</code>
+     */
+    public SRURequestAuthenticator getRequestAuthenticator() {
+        return requestAuthenticator;
     }
 
@@ -142,4 +153,5 @@
             this.httpContext = null;
         }
+        this.requestAuthenticator = builder.requestAuthenticator;
         this.threadCount      = builder.threadCount;
         if (builder.recordParsers != null) {
@@ -170,4 +182,5 @@
         private CloseableHttpClient httpClient = null;
         private HttpClientContext httpContext = null;
+        private SRURequestAuthenticator requestAuthenticator;
         private int threadCount =
                 Runtime.getRuntime().availableProcessors() * 2;
@@ -271,4 +284,11 @@
 
 
+        public Builder setRequestAuthenticator(
+                SRURequestAuthenticator requestAuthenticator) {
+            this.requestAuthenticator = requestAuthenticator;
+            return this;
+        }
+
+
         /**
          * Set the number of worker threads. This value is only relevant for the
Index: /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUExplainRequest.java
===================================================================
--- /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUExplainRequest.java	(revision 7265)
+++ /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUExplainRequest.java	(revision 7266)
@@ -105,5 +105,5 @@
 
     @Override
-    SRUOperation getOperation() {
+    public SRUOperation getOperation() {
         return SRUOperation.EXPLAIN;
     }
Index: /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUOperation.java
===================================================================
--- /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUOperation.java	(revision 7266)
+++ /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUOperation.java	(revision 7266)
@@ -0,0 +1,39 @@
+/**
+ * This software is copyright (c) 2011-2021 by
+ *  - Leibniz-Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
+ * This is free software. You can redistribute it
+ * and/or modify it under the terms described in
+ * the GNU General Public License v3 of which you
+ * should have received a copy. Otherwise you can download
+ * it from
+ *
+ *   http://www.gnu.org/licenses/gpl-3.0.txt
+ *
+ * @copyright Leibniz-Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
+ *
+ * @license http://www.gnu.org/licenses/gpl-3.0.txt
+ *  GNU General Public License v3
+ */
+package eu.clarin.sru.client;
+
+/**
+ * SRU operation.
+ */
+
+public enum SRUOperation {
+    /**
+     * A <em>explain</em> operation
+     */
+    EXPLAIN,
+
+    /**
+     * A <em>scan</em> operation
+     */
+
+    SCAN,
+
+    /**
+     * A <em>searchRetrieve</em> operation
+     */
+    SEARCH_RETRIEVE
+} // enum SRUOperation
Index: /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRURequestAuthenticator.java
===================================================================
--- /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRURequestAuthenticator.java	(revision 7266)
+++ /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRURequestAuthenticator.java	(revision 7266)
@@ -0,0 +1,34 @@
+/**
+ * This software is copyright (c) 2011-2021 by
+ *  - Leibniz-Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
+ * This is free software. You can redistribute it
+ * and/or modify it under the terms described in
+ * the GNU General Public License v3 of which you
+ * should have received a copy. Otherwise you can download
+ * it from
+ *
+ *   http://www.gnu.org/licenses/gpl-3.0.txt
+ *
+ * @copyright Leibniz-Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
+ *
+ * @license http://www.gnu.org/licenses/gpl-3.0.txt
+ *  GNU General Public License v3
+ */
+package eu.clarin.sru.client;
+
+public interface SRURequestAuthenticator {
+
+    /**
+     * Make an HTTP Authentication header value fur a SRU request. This method
+     * must return a valid HTTP Authentication header value or <code>null</code>
+     * if no authentication for this endpoint and/or operation is required.
+     *
+     * @param operation
+     *            the SRU operation for the request
+     * @param endpointURI
+     *            the endpoint base URI
+     * @return or authentication header value or <code>null</code>
+     */
+    public String createAuthenticationHeaderValue(SRUOperation operation, String endpointURI);
+
+} // interface SRURequestAuthenticator
Index: /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUScanRequest.java
===================================================================
--- /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUScanRequest.java	(revision 7265)
+++ /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUScanRequest.java	(revision 7266)
@@ -152,5 +152,5 @@
 
     @Override
-    SRUOperation getOperation() {
+    public SRUOperation getOperation() {
         return SRUOperation.SCAN;
     }
Index: /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUSearchRetrieveRequest.java
===================================================================
--- /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUSearchRetrieveRequest.java	(revision 7265)
+++ /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUSearchRetrieveRequest.java	(revision 7266)
@@ -313,5 +313,5 @@
 
     @Override
-    SRUOperation getOperation() {
+    public SRUOperation getOperation() {
         return SRUOperation.SEARCH_RETRIEVE;
     }
Index: /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUSimpleClient.java
===================================================================
--- /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUSimpleClient.java	(revision 7265)
+++ /SRUClient/trunk/src/main/java/eu/clarin/sru/client/SRUSimpleClient.java	(revision 7266)
@@ -85,4 +85,5 @@
     private final CloseableHttpClient httpClient;
     private final HttpContext httpContext;
+    private final SRURequestAuthenticator requestAuthenticator;
     private final XmlStreamReaderProxy proxy = new XmlStreamReaderProxy();
     private final SRUExplainRecordDataParser explainRecordParser =
@@ -124,5 +125,4 @@
             }
         }
-
         final CloseableHttpClient client = config.getCustomizedHttpClient();
         if (client != null) {
@@ -136,4 +136,5 @@
             httpContext = null;
         }
+        this.requestAuthenticator = config.getRequestAuthenticator();
     }
 
@@ -168,5 +169,5 @@
         // create URI and perform request
         final URI uri = request.makeURI(defaultVersion);
-        CloseableHttpResponse response = executeRequest(uri);
+        CloseableHttpResponse response = executeRequest(uri, request);
         InputStream stream             = null;
         SRUXMLStreamReader reader      = null;
@@ -258,5 +259,5 @@
         // create URI and perform request
         final URI uri = request.makeURI(defaultVersion);
-        CloseableHttpResponse response = executeRequest(uri);
+        CloseableHttpResponse response = executeRequest(uri, request);
         InputStream stream             = null;
         SRUXMLStreamReader reader      = null;
@@ -347,5 +348,5 @@
         // create URI and perform request
         final URI uri = request.makeURI(defaultVersion);
-        CloseableHttpResponse response = executeRequest(uri);
+        CloseableHttpResponse response = executeRequest(uri, request);
         InputStream stream             = null;
         SRUXMLStreamReader reader      = null;
@@ -407,17 +408,31 @@
 
 
-    private CloseableHttpResponse executeRequest(URI uri)
-            throws SRUClientException {
+    private CloseableHttpResponse executeRequest(URI requestUri,
+            SRUAbstractRequest sruRequest) throws SRUClientException {
         CloseableHttpResponse response = null;
         boolean forceClose             = true;
         try {
-            logger.debug("submitting HTTP request: {}", uri.toString());
             try {
-                HttpGet request = new HttpGet(uri);
+                HttpGet request = new HttpGet(requestUri);
+                if (requestAuthenticator != null) {
+                    String value = requestAuthenticator.createAuthenticationHeaderValue(
+                            sruRequest.getOperation(),
+                            sruRequest.getBaseURI().toString());
+                    if (value != null) {
+                        value = value.trim();
+                        if (!value.isEmpty()) {
+                            logger.debug("adding HTTP authentication header with value: {}", value);
+                            request.addHeader("Authentication", value);
+                        } else {
+                            logger.error("request authenticator returned an empty header value!");
+                        }
+                    }
+                }
+                logger.debug("submitting HTTP request: {}", requestUri.toString());
                 response = httpClient.execute(request, httpContext);
                 StatusLine status = response.getStatusLine();
                 if (status.getStatusCode() != HttpStatus.SC_OK) {
                     if (status.getStatusCode() == HttpStatus.SC_NOT_FOUND) {
-                        throw new SRUClientException("not found: " + uri);
+                        throw new SRUClientException("not found: " + requestUri);
                     } else {
                         throw new SRUClientException("unexpected status: " +
@@ -431,5 +446,5 @@
             } catch (UnknownHostException e) {
                 throw new SRUClientException(
-                        "unknown host: " + uri.getHost(), e);
+                        "unknown host: " + requestUri.getHost(), e);
             } catch (IOException e) {
                 String msg = null;
@@ -1279,5 +1294,5 @@
                     (diagnostics == null), strictMode)) != null) {
                 if (diagnostics == null) {
-                    diagnostics = new ArrayList<SRUDiagnostic>();
+                    diagnostics = new ArrayList<>();
                 }
                 diagnostics.add(diagnostic);
