Repository: wso2/product-microgateway
Issue: Token validation is successful with malformed Authorization header

### Description:
Token validation is successful in the following scenarios.

1. Authorization: <TOKEN>
2. Authorization: Bearer <TOKEN>
3. Authorization: something <TOKEN>

This behaviour is a bug since the correct Authorization header format is not honoured.

### Steps to reproduce:

### 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:
integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testCases/jwtValidator/JwtTestCase.java
enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java
enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APISecurityConstants.java
enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/oauth/OAuthAuthenticator.java
enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/validator/JWTConstants.java

diff --git a/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APISecurityConstants.java b/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APISecurityConstants.java
index 94d4c96e5..c3b06d008 100644
--- a/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APISecurityConstants.java
+++ b/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/constants/APISecurityConstants.java
@@ -34,7 +34,7 @@ public class APISecurityConstants {
     public static final int API_AUTH_MISSING_CREDENTIALS = 900902;
     public static final String API_AUTH_MISSING_CREDENTIALS_MESSAGE = "Missing Credentials";
     public static final String API_AUTH_MISSING_CREDENTIALS_DESCRIPTION = "Make sure your API invocation call "
-            + "has a header: ";
+            + "has a header: Authorization: Bearer ACCESS_TOKEN";
 
     public static final int API_AUTH_ACCESS_TOKEN_EXPIRED = 900903;
     public static final String API_AUTH_ACCESS_TOKEN_EXPIRED_MESSAGE = "Access Token Expired";
diff --git a/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java b/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java
index 640fa3ecd..125763080 100644
--- a/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java
+++ b/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/JWTAuthenticator.java
@@ -86,7 +86,11 @@ public class JWTAuthenticator implements Authenticator {
     @Override
     public AuthenticationContext authenticate(RequestContext requestContext) throws APISecurityException {
         String jwtToken = retrieveAuthHeaderValue(requestContext);
-        String splitToken[] = jwtToken.split("\\\\s");
+        if (jwtToken == null || !jwtToken.toLowerCase().contains(JWTConstants.BEARER)) {
+            throw new APISecurityException(APIConstants.StatusCodes.UNAUTHENTICATED.getCode(),
+                    APISecurityConstants.API_AUTH_MISSING_CREDENTIALS, "Missing Credentials");
+        }
+        String[] splitToken = jwtToken.split("\\\\s");
         // Extract the token when it is sent as bearer token. i.e Authorization: Bearer <token>
         if (splitToken.length > 1) {
             jwtToken = splitToken[1];
diff --git a/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/validator/JWTConstants.java b/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/validator/JWTConstants.java
index 138f85b34..a2e3f1923 100644
--- a/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/validator/JWTConstants.java
+++ b/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/jwt/validator/JWTConstants.java
@@ -24,6 +24,7 @@ package org.wso2.choreo.connect.enforcer.security.jwt.validator;
 public class JWTConstants {
     public static final String AUTHORIZATION = "authorization";
     public static final String RSA = "RSA";
+    public static final String BEARER = "bearer";
     public static final String UNAVAILABLE = "Token is not available in cache";
     public static final String VALID = "valid";
     public static final String INVALID = "invalid";
diff --git a/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/oauth/OAuthAuthenticator.java b/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/oauth/OAuthAuthenticator.java
index 5cbdcf2ae..5e2ea1662 100644
--- a/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/oauth/OAuthAuthenticator.java
+++ b/enforcer/src/main/java/org/wso2/choreo/connect/enforcer/security/oauth/OAuthAuthenticator.java
@@ -31,6 +31,9 @@ import org.apache.http.client.methods.HttpPost;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.message.BasicNameValuePair;
 import org.wso2.choreo.connect.enforcer.api.RequestContext;
+import org.wso2.choreo.connect.enforcer.constants.APIConstants;
+import org.wso2.choreo.connect.enforcer.constants.APISecurityConstants;
+import org.wso2.choreo.connect.enforcer.exception.APISecurityException;
 import org.wso2.choreo.connect.enforcer.security.AccessTokenInfo;
 import org.wso2.choreo.connect.enforcer.security.AuthenticationContext;
 import org.wso2.choreo.connect.enforcer.security.Authenticator;
@@ -91,13 +94,15 @@ public class OAuthAuthenticator implements Authenticator {
     }
 
     @Override
-    public AuthenticationContext authenticate(RequestContext requestContext) {
+    public AuthenticationContext authenticate(RequestContext requestContext) throws APISecurityException {
         String token = requestContext.getHeaders().get("authorization");
         AccessTokenInfo accessTokenInfo = new AccessTokenInfo();
 
-        if (token.toLowerCase().contains("bearer")) {
-            token = token.split("\\\\s")[1];
+        if (token == null || !token.toLowerCase().contains("bearer")) {
+            throw new APISecurityException(APIConstants.StatusCodes.UNAUTHENTICATED.getCode(),
+                    APISecurityConstants.API_AUTH_MISSING_CREDENTIALS, "Missing Credentials");
         }
+        token = token.split("\\\\s")[1];
 
         try {
             IntrospectInfo introspectInfo = validateToken(token);
diff --git a/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testCases/jwtValidator/JwtTestCase.java b/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testCases/jwtValidator/JwtTestCase.java
index d162dcf63..1be3210ac 100644
--- a/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testCases/jwtValidator/JwtTestCase.java
+++ b/integration/test-integration/src/test/java/org/wso2/choreo/connect/tests/testCases/jwtValidator/JwtTestCase.java
@@ -80,6 +80,19 @@ public class JwtTestCase {
         Assert.assertEquals(response.getResponseCode(), HttpStatus.SC_UNAUTHORIZED, "Response code mismatched");
     }
 
+    @Test(description = "Test to check the invalid authorization header format")
+    public void invokeJWTHeaderInvalidAuthorizationHeader() throws Exception {
+
+        // Set header
+        Map<String, String> headers = new HashMap<String, String>();
+        headers.put(HttpHeaderNames.AUTHORIZATION.toString(), "Something " + TestConstant.INVALID_JWT_TOKEN);
+        HttpResponse response = HttpsClientRequest.doGet(Utils.getServiceURLHttps(
+                "/v2/pet/2") , headers);
+
+        Assert.assertNotNull(response);
+        Assert.assertEquals(response.getResponseCode(), HttpStatus.SC_UNAUTHORIZED, "Response code mismatched");
+    }
+
     @Test(description = "Test to check the JWT auth validate expired token")
     public void invokeJWTHeaderExpiredTokenTest() throws Exception {