Repository: wso2/product-microgateway
Issue: backend basic auth security not working when API is not not secured

### Description:
<!-- Describe the issue -->

### Steps to reproduce:
create api.
disable security for an resource.
add production endpoint basic auth security
deploy and invoke the resource.
backend call does not have basic auth header

### Affected Product Version:
<!-- Members can use Affected/*** labels -->

### Environment details (with versions):
- OS:
- Client:
- Env (Docker/K8s):

---
### Optional Fields
#### Related Issues:
<!-- Any related issues from this/other repositories-->

#### Suggested Labels:
<!--Only to be used by non-members-->

#### Suggested Assignees:
<!--Only to be used by non-members-->


Changed files:
enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyAuthenticator.java
enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/InternalAPIKeyAuthenticator.java
integration/mock-backend-server/src/main/java/org/wso2/choreo/connect/mockbackend/MockBackendProd.java
enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/util/EndpointSecurityUtils.java
integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testcases/withapim/BackendSecurityTestCase.java
enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/AuthFilter.java
enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java

diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/AuthFilter.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/AuthFilter.java
index a1687eeb8..d83d0e2c3 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/AuthFilter.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/AuthFilter.java
@@ -37,6 +37,7 @@ import org.wso2.choreo.connect.enforcer.security.jwt.APIKeyAuthenticator;
 import org.wso2.choreo.connect.enforcer.security.jwt.InternalAPIKeyAuthenticator;
 import org.wso2.choreo.connect.enforcer.security.jwt.JWTAuthenticator;
 import org.wso2.choreo.connect.enforcer.security.jwt.UnsecuredAPIAuthenticator;
+import org.wso2.choreo.connect.enforcer.util.EndpointSecurityUtils;
 import org.wso2.choreo.connect.enforcer.util.FilterUtils;
 
 import java.util.ArrayList;
@@ -153,6 +154,8 @@ public class AuthFilter implements Filter {
             requestContext.setAuthenticationContext(authenticate);
             if (authenticate.isAuthenticated()) {
                 updateClusterHeaderAndCheckEnv(requestContext, authenticate);
+                // set backend security
+                EndpointSecurityUtils.addEndpointSecurity(requestContext);
                 return new AuthenticationResponse(true, false,
                         false);
             }
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyAuthenticator.java
index 222fb4294..c53c76234 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyAuthenticator.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/APIKeyAuthenticator.java
@@ -43,7 +43,6 @@ import org.wso2.choreo.connect.enforcer.dto.APIKeyValidationInfoDTO;
 import org.wso2.choreo.connect.enforcer.dto.JWTTokenPayloadInfo;
 import org.wso2.choreo.connect.enforcer.exception.APISecurityException;
 import org.wso2.choreo.connect.enforcer.util.BackendJwtUtils;
-import org.wso2.choreo.connect.enforcer.util.EndpointSecurityUtils;
 import org.wso2.choreo.connect.enforcer.util.FilterUtils;
 import org.wso2.choreo.connect.enforcer.util.JWTUtils;
 
@@ -251,9 +250,6 @@ public class APIKeyAuthenticator extends APIKeyHandler {
                 // Get APIKeyValidationInfoDTO
                 APIKeyValidationInfoDTO apiKeyValidationInfoDTO = getAPIKeyValidationDTO(requestContext, payload);
 
-                // Sets endpoint security
-                EndpointSecurityUtils.addEndpointSecurity(requestContext, apiKeyValidationInfoDTO);
-
                 // TODO: Add analytics data processing
 
                 // Get SignedJWTInfo
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/InternalAPIKeyAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/InternalAPIKeyAuthenticator.java
index 8e6a94053..92469e697 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/InternalAPIKeyAuthenticator.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/InternalAPIKeyAuthenticator.java
@@ -44,7 +44,6 @@ import org.wso2.choreo.connect.enforcer.tracing.TracingSpan;
 import org.wso2.choreo.connect.enforcer.tracing.TracingTracer;
 import org.wso2.choreo.connect.enforcer.tracing.Utils;
 import org.wso2.choreo.connect.enforcer.util.BackendJwtUtils;
-import org.wso2.choreo.connect.enforcer.util.EndpointSecurityUtils;
 import org.wso2.choreo.connect.enforcer.util.FilterUtils;
 
 import java.text.ParseException;
@@ -210,9 +209,6 @@ public class InternalAPIKeyAuthenticator extends APIKeyHandler {
                     //Get APIKeyValidationInfoDTO for internal key with limited info
                     APIKeyValidationInfoDTO apiKeyValidationInfoDTO = getAPIKeyValidationDTO(requestContext, payload);
 
-                    // Sets endpoint security
-                    EndpointSecurityUtils.addEndpointSecurity(requestContext, apiKeyValidationInfoDTO);
-
                     // Generate or get backend JWT
                     JWTConfigurationDto jwtConfigurationDto = ConfigHolder.getInstance().
                             getConfig().getJwtConfigurationDto();
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java
index 00439e100..3c31fad10 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java
@@ -54,7 +54,6 @@ import org.wso2.choreo.connect.enforcer.tracing.TracingSpan;
 import org.wso2.choreo.connect.enforcer.tracing.TracingTracer;
 import org.wso2.choreo.connect.enforcer.tracing.Utils;
 import org.wso2.choreo.connect.enforcer.util.BackendJwtUtils;
-import org.wso2.choreo.connect.enforcer.util.EndpointSecurityUtils;
 import org.wso2.choreo.connect.enforcer.util.FilterUtils;
 import org.wso2.choreo.connect.enforcer.util.JWTUtils;
 
@@ -237,9 +236,6 @@ public class JWTAuthenticator implements Authenticator {
                     }
                     log.debug("JWT authentication successful.");
 
-                    // Set endpoint security
-                    EndpointSecurityUtils.addEndpointSecurity(requestContext, apiKeyValidationInfoDTO);
-
                     // Generate or get backend JWT
                     String endUserToken = null;
                     JWTConfigurationDto backendJwtConfig = ConfigHolder.getInstance().getConfig().
diff --git a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/util/EndpointSecurityUtils.java b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/util/EndpointSecurityUtils.java
index 39b56f5b0..d2d5e05eb 100644
--- a/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/util/EndpointSecurityUtils.java
+++ b/enforcer-parent/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/util/EndpointSecurityUtils.java
@@ -21,7 +21,6 @@ package org.wso2.choreo.connect.enforcer.util;
 import org.wso2.choreo.connect.enforcer.commons.model.RequestContext;
 import org.wso2.choreo.connect.enforcer.commons.model.SecurityInfo;
 import org.wso2.choreo.connect.enforcer.constants.APIConstants;
-import org.wso2.choreo.connect.enforcer.dto.APIKeyValidationInfoDTO;
 
 import java.util.Base64;
 
@@ -34,30 +33,31 @@ public class EndpointSecurityUtils {
      * Adds the backend endpoint security header to the given requestContext.
      *
      * @param requestContext requestContext instance to add the backend endpoint security header
-     * @param apiKeyValidationInfoDTO apiKeyValidationInfoDTO containing necessary info
      */
-    public static void addEndpointSecurity(RequestContext requestContext,
-                                                    APIKeyValidationInfoDTO apiKeyValidationInfoDTO) {
-        SecurityInfo securityInfo;
-        if (apiKeyValidationInfoDTO.getType() != null &&
-                requestContext.getMatchedAPI().getEndpointSecurity() != null) {
-            if (apiKeyValidationInfoDTO.getType().equals(APIConstants.API_KEY_TYPE_PRODUCTION)) {
+    public static void addEndpointSecurity(RequestContext requestContext) {
+        SecurityInfo securityInfo = null;
+        String keyType = "";
+        if (requestContext.getAuthenticationContext() != null) {
+            keyType = requestContext.getAuthenticationContext().getKeyType();
+        }
+        if (requestContext.getMatchedAPI().getEndpointSecurity() != null) {
+            if (APIConstants.API_KEY_TYPE_PRODUCTION.equals(keyType)) {
                 securityInfo = requestContext.getMatchedAPI().getEndpointSecurity().
                         getProductionSecurityInfo();
             } else {
                 securityInfo = requestContext.getMatchedAPI().getEndpointSecurity().
                         getSandBoxSecurityInfo();
             }
-            if (securityInfo != null && securityInfo.isEnabled() &&
-                    APIConstants.AUTHORIZATION_HEADER_BASIC.
-                            equalsIgnoreCase(securityInfo.getSecurityType())) {
-                requestContext.getRemoveHeaders().remove(APIConstants.AUTHORIZATION_HEADER_DEFAULT
-                        .toLowerCase());
-                requestContext.addOrModifyHeaders(APIConstants.AUTHORIZATION_HEADER_DEFAULT,
-                        APIConstants.AUTHORIZATION_HEADER_BASIC + ' ' +
-                                Base64.getEncoder().encodeToString((securityInfo.getUsername() +
-                                        ':' + String.valueOf(securityInfo.getPassword())).getBytes()));
-            }
+        }
+        if (securityInfo != null && securityInfo.isEnabled() &&
+                APIConstants.AUTHORIZATION_HEADER_BASIC.
+                        equalsIgnoreCase(securityInfo.getSecurityType())) {
+            requestContext.getRemoveHeaders().remove(APIConstants.AUTHORIZATION_HEADER_DEFAULT
+                    .toLowerCase());
+            requestContext.addOrModifyHeaders(APIConstants.AUTHORIZATION_HEADER_DEFAULT,
+                    APIConstants.AUTHORIZATION_HEADER_BASIC + ' ' +
+                            Base64.getEncoder().encodeToString((securityInfo.getUsername() +
+                                    ':' + String.valueOf(securityInfo.getPassword())).getBytes()));
         }
     }
 }
diff --git a/integration/mock-backend-server/src/main/java/org/wso2/choreo/connect/mockbackend/MockBackendProd.java b/integration/mock-backend-server/src/main/java/org/wso2/choreo/connect/mockbackend/MockBackendProd.java
index 3851bdaf4..4ddf8c491 100644
--- a/integration/mock-backend-server/src/main/java/org/wso2/choreo/connect/mockbackend/MockBackendProd.java
+++ b/integration/mock-backend-server/src/main/java/org/wso2/choreo/connect/mockbackend/MockBackendProd.java
@@ -291,6 +291,7 @@ public class MockBackendProd extends Thread {
             //                                             response flow headers to interceptor service
             // sent request body in response body
             httpServer.createContext(context + "/echo", Utils::echo);
+            httpServer.createContext(context + "/echo2", Utils::echo);
 
             httpServer.start();
         } catch (Exception ex) {
diff --git a/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testcases/withapim/BackendSecurityTestCase.java b/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testcases/withapim/BackendSecurityTestCase.java
index ef1d33e75..f25d38fc7 100644
--- a/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testcases/withapim/BackendSecurityTestCase.java
+++ b/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testcases/withapim/BackendSecurityTestCase.java
@@ -81,8 +81,15 @@ public class BackendSecurityTestCase extends ApimBaseTest {
         apiOperation.setTarget("/echo");
         apiOperation.setThrottlingPolicy(TestConstant.API_TIER.UNLIMITED);
 
+        APIOperationsDTO apiOperation2 = new APIOperationsDTO();
+        apiOperation2.setVerb("GET");
+        apiOperation2.setTarget("/echo2");
+        apiOperation2.setThrottlingPolicy(TestConstant.API_TIER.UNLIMITED);
+        apiOperation2.setAuthType("None");
+
         List<APIOperationsDTO> operationsDTOS = new ArrayList<>();
         operationsDTOS.add(apiOperation);
+        operationsDTOS.add(apiOperation2);
 
         APIRequest apiRequest = PublisherUtils.createSampleAPIRequest(API_NAME, API_CONTEXT,
                 API_VERSION, user.getUserName());
@@ -102,17 +109,29 @@ public class BackendSecurityTestCase extends ApimBaseTest {
         Utils.delay(TestConstant.DEPLOYMENT_WAIT_TIME * 2, "Interrupted when waiting for the " +
                 "subscription to be deployed");
 
+        //test 1 - jwt secured resource
         //Invoke API
         Map<String, String> headers = new HashMap<>();
         headers.put(HttpHeaders.AUTHORIZATION, "Bearer " + accessToken);
         String endpoint = Utils.getServiceURLHttps(API_CONTEXT + "/1.0.0/echo");
         HttpResponse response = HttpsClientRequest.doGet(endpoint, headers);
-        Assert.assertNotNull(response, "Error occurred while invoking the endpoint " + endpoint + " HttpResponse ");
+        Assert.assertNotNull(response, "Error occurred while invoking the endpoint " + endpoint);
 
         // test headers
         Map<String, String> respHeaders = response.getHeaders();
         Assert.assertTrue(respHeaders.containsKey("authorization"), "Backend did not receive auth header");
         Assert.assertEquals(respHeaders.get("authorization"), "Basic YWRtaW46YWRtaW4=",
                 "backend basic auth header is incorrect");
+
+        //test 2 - invoke non secured resource
+        endpoint = Utils.getServiceURLHttps(API_CONTEXT + "/1.0.0/echo2");
+        response = HttpsClientRequest.doGet(endpoint);
+        Assert.assertNotNull(response, "Error occurred while invoking the endpoint " + endpoint);
+
+        // test headers
+        respHeaders = response.getHeaders();
+        Assert.assertTrue(respHeaders.containsKey("authorization"), "Backend did not receive auth header");
+        Assert.assertEquals(respHeaders.get("authorization"), "Basic YWRtaW46YWRtaW4=",
+                "backend basic auth header is incorrect");
     }
 }