Repository: helidon-io/helidon (java)

Issue:
SecurityPreMatchingFilter is overriding the SecurityContext when using webserver security
## Environment Details
* Helidon Version: 2.5.4
* Helidon MP
* JDK version: 17.0.3
* OS: Mac OS
* Docker version (if applicable): N/A

----------

## Problem Description
An authenticated SecurityContext is being replaced by an unauthenticated one after all filters are executed
## Steps to reproduce
Setup Helidon Security using "web server security". Example:
```
security:
  providers:
    - spectra-auth:
        idcsTenantCertChain: '<idcsTenantCertChain>'
        authentication:
          authenticate: true
        audience: "<audience>"
        idcsUrl: "<idcsUrl>"
        scope: "<scope>"
  web-server:
    paths:
      # authenticate all paths
      - path: "/myapplication/*"
        authenticate: true
        spectra-auth:
          authentication:
            authenticate: true
``` 
Put a break point in the following lines in SecurityPreMatchingFilter:
```
    public void filter(ContainerRequestContext request) {
        SecurityTracing tracing = SecurityTracing.get(); // BREAK POINT 1
        SecurityContext securityContext = this.security().contextBuilder(Integer.toString(CONTEXT_COUNTER.incrementAndGet(), 36)).tracingSpan((SpanContext)tracing.findParent().orElse((Object)null)).build();
        Contexts.context().ifPresent((ctx) -> {
            ctx.register(securityContext);
        });
        ((Ref)this.injectionManager.getInstance((new GenericType<Ref<SecurityContext>>() {
        }).getType())).set(securityContext);  // BREAK POINT 2
        if (this.featureConfig().shouldUsePrematchingAuthentication()) {
            this.doFilter(request, securityContext);
        }

    }
```
In debug mode, execute a request using a valid Bearer Token.
This is the result when executing expressions in both break points:
- Break Point 1
  - Contexts.context().get().get(SecurityContext.class).get().isAuthenticated()
    - Result: true
  - Contexts.context().get().get(SecurityContext.class).get().userName()
    - Result: <authenticated_username>
- Break Point 2
  - Contexts.context().get().get(SecurityContext.class).get().isAuthenticated()
    - Result: false
  - Contexts.context().get().get(SecurityContext.class).get().userName()
    - Result: null

In other words this this the block replacing the existing SecurityContext:
```
        Contexts.context().ifPresent((ctx) -> {
            ctx.register(securityContext);
        });
```



Pull request:
Remove public constructors from production types.
Resolves #6414 

Patch:
diff --git a/nima/common/tls/src/main/java/io/helidon/nima/common/tls/TrustAllManagerFactory.java b/nima/common/tls/src/main/java/io/helidon/nima/common/tls/TrustAllManagerFactory.java
index 85896ae0d3..7c53583de0 100644
--- a/nima/common/tls/src/main/java/io/helidon/nima/common/tls/TrustAllManagerFactory.java
+++ b/nima/common/tls/src/main/java/io/helidon/nima/common/tls/TrustAllManagerFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Oracle and/or its affiliates.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ import static java.lang.System.Logger.Level.TRACE;
 /**
  * A trust manager factory that trusts all peers.
  */
-public class TrustAllManagerFactory extends TrustManagerFactory {
+class TrustAllManagerFactory extends TrustManagerFactory {
     private static final TrustAllManagerFactorySpi SPI = new TrustAllManagerFactorySpi();
     private static final Provider PROVIDER = new Provider("helidon",
                                                           "0.0",
@@ -43,7 +43,7 @@ public class TrustAllManagerFactory extends TrustManagerFactory {
     /**
      * Create a new instance.
      */
-    public TrustAllManagerFactory() {
+    TrustAllManagerFactory() {
         super(SPI, PROVIDER, "insecure-trust-all");
     }
 
diff --git a/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2ConnectionWriter.java b/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2ConnectionWriter.java
index fd9734311b..b2b6f294a7 100755
--- a/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2ConnectionWriter.java
+++ b/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2ConnectionWriter.java
@@ -53,7 +53,7 @@ public class Http2ConnectionWriter implements Http2StreamWriter {
 
         // initial size is based on our settings, then updated with client settings
         this.outboundDynamicTable = Http2Headers.DynamicTable.create(Http2Setting.HEADER_TABLE_SIZE.defaultValue());
-        this.responseHuffman = new Http2HuffmanEncoder();
+        this.responseHuffman = Http2HuffmanEncoder.create();
     }
 
     @Override
diff --git a/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2HuffmanDecoder.java b/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2HuffmanDecoder.java
index 7f80de99a1..c22a71aab5 100644
--- a/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2HuffmanDecoder.java
+++ b/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2HuffmanDecoder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Oracle and/or its affiliates.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -40,7 +40,7 @@ import java.util.function.BiFunction;
 import io.helidon.common.buffers.BufferData;
 
 /**
- * Implementation of HPack Huffman decoding and encoding.
+ * Implementation of HPack Huffman decoding.
  */
 public class Http2HuffmanDecoder {
     private static final String EMPTY_STRING = "";
@@ -54,7 +54,16 @@ public class Http2HuffmanDecoder {
     /**
      * Huffman decoder.
      */
-    public Http2HuffmanDecoder() {
+    private Http2HuffmanDecoder() {
+    }
+
+    /**
+     * Creates a new HPack Huffman decoder.
+     *
+     * @return a new Huffman decoder
+     */
+    public static Http2HuffmanDecoder create() {
+        return new Http2HuffmanDecoder();
     }
 
     /**
diff --git a/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2HuffmanEncoder.java b/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2HuffmanEncoder.java
index 6dbfcd3c96..974b01729e 100644
--- a/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2HuffmanEncoder.java
+++ b/nima/http2/http2/src/main/java/io/helidon/nima/http2/Http2HuffmanEncoder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Oracle and/or its affiliates.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ package io.helidon.nima.http2;
 import io.helidon.common.buffers.BufferData;
 
 /**
- * Implementation of HPack Huffman decoding and encoding.
+ * Implementation of HPack Huffman encoding.
  */
 public class Http2HuffmanEncoder {
     private static final int HUFFMAN_ENCODED = 1 << 7;
@@ -45,7 +45,16 @@ public class Http2HuffmanEncoder {
     /**
      * Huffman encoder.
      */
-    public Http2HuffmanEncoder() {
+    private Http2HuffmanEncoder() {
+    }
+
+    /**
+     * Creates a new HPack Huffman encoder.
+     *
+     * @return a new Huffman encoder
+     */
+    public static Http2HuffmanEncoder create() {
+        return new Http2HuffmanEncoder();
     }
 
     void encode(BufferData buffer, String string) {
diff --git a/nima/http2/webclient/src/main/java/io/helidon/nima/http2/webclient/Http2ClientStream.java b/nima/http2/webclient/src/main/java/io/helidon/nima/http2/webclient/Http2ClientStream.java
index c55f81c812..c35f8399bb 100644
--- a/nima/http2/webclient/src/main/java/io/helidon/nima/http2/webclient/Http2ClientStream.java
+++ b/nima/http2/webclient/src/main/java/io/helidon/nima/http2/webclient/Http2ClientStream.java
@@ -292,7 +292,7 @@ class Http2ClientStream implements Http2Stream, ReleasableResource {
             case HEADERS, CONTINUATION:
                 continuationData.add(frameData);
                 if (endOfHeaders) {
-                    var requestHuffman = new Http2HuffmanDecoder();
+                    var requestHuffman = Http2HuffmanDecoder.create();
                     Http2Headers http2Headers = Http2Headers.create(this,
                                                                     connection.getInboundDynamicTable(),
                                                                     requestHuffman,
diff --git a/nima/http2/webserver/src/main/java/io/helidon/nima/http2/webserver/Http2Connection.java b/nima/http2/webserver/src/main/java/io/helidon/nima/http2/webserver/Http2Connection.java
index 6eef03a407..44abe02eb4 100755
--- a/nima/http2/webserver/src/main/java/io/helidon/nima/http2/webserver/Http2Connection.java
+++ b/nima/http2/webserver/src/main/java/io/helidon/nima/http2/webserver/Http2Connection.java
@@ -125,7 +125,7 @@ public class Http2Connection implements ServerConnection, InterruptableTask<Void
         this.subProviders = subProviders;
         this.requestDynamicTable = Http2Headers.DynamicTable.create(
                 serverSettings.value(Http2Setting.HEADER_TABLE_SIZE));
-        this.requestHuffman = new Http2HuffmanDecoder();
+        this.requestHuffman = Http2HuffmanDecoder.create();
         this.routing = ctx.router().routing(HttpRouting.class, HttpRouting.empty());
         this.reader = ctx.dataReader();
         this.sendErrorDetails = http2Config.sendErrorDetails();


Test patch:
diff --git a/nima/http2/http2/src/test/java/io/helidon/nima/http2/Http2HeadersTest.java b/nima/http2/http2/src/test/java/io/helidon/nima/http2/Http2HeadersTest.java
index d2c3e247a4..d41ec254b9 100644
--- a/nima/http2/http2/src/test/java/io/helidon/nima/http2/Http2HeadersTest.java
+++ b/nima/http2/http2/src/test/java/io/helidon/nima/http2/Http2HeadersTest.java
@@ -171,7 +171,7 @@ class Http2HeadersTest {
         http2Headers.path("/");
         http2Headers.authority("www.example.com");
 
-        Http2HuffmanEncoder huffman = new Http2HuffmanEncoder();
+        Http2HuffmanEncoder huffman = Http2HuffmanEncoder.create();
 
         BufferData buffer = BufferData.growing(32);
         http2Headers.write(dynamicTable, huffman, buffer);
@@ -262,7 +262,7 @@ class Http2HeadersTest {
 
         return Http2Headers.create(stream,
                                    dynamicTable,
-                                   new Http2HuffmanDecoder(),
+                                   Http2HuffmanDecoder.create(),
                                    new Http2FrameData(header, data));
     }
 }
\ No newline at end of file
diff --git a/nima/http2/http2/src/test/java/io/helidon/nima/http2/Http2HuffmanTest.java b/nima/http2/http2/src/test/java/io/helidon/nima/http2/Http2HuffmanTest.java
index 7e59805f0e..865a69223b 100644
--- a/nima/http2/http2/src/test/java/io/helidon/nima/http2/Http2HuffmanTest.java
+++ b/nima/http2/http2/src/test/java/io/helidon/nima/http2/Http2HuffmanTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2022 Oracle and/or its affiliates.
+ * Copyright (c) 2022, 2023 Oracle and/or its affiliates.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,8 +26,8 @@ import static org.hamcrest.MatcherAssert.assertThat;
 class Http2HuffmanTest {
     @Test
     void testEncodeDecode() {
-        Http2HuffmanEncoder enc = new Http2HuffmanEncoder();
-        Http2HuffmanDecoder dec = new Http2HuffmanDecoder();
+        Http2HuffmanEncoder enc = Http2HuffmanEncoder.create();
+        Http2HuffmanDecoder dec = Http2HuffmanDecoder.create();
 
         String value = "my very nice long value";
         BufferData result = BufferData.growing(32);