diff --git a/src/main/java/org/opensearch/security/http/OnBehalfOfAuthenticator.java b/src/main/java/org/opensearch/security/http/OnBehalfOfAuthenticator.java
index 8499b88f62..4ac3be335f 100644
--- a/src/main/java/org/opensearch/security/http/OnBehalfOfAuthenticator.java
+++ b/src/main/java/org/opensearch/security/http/OnBehalfOfAuthenticator.java
@@ -145,11 +145,6 @@ private AuthCredentials extractCredentials0(final SecurityRequest request) {
             return null;
         }
 
-        if (jwtParser == null) {
-            log.error("Missing Signing Key. JWT authentication will not work");
-            return null;
-        }
-
         String jwtToken = extractJwtFromHeader(request);
         if (jwtToken == null) {
             return null;
@@ -193,6 +188,7 @@ private AuthCredentials extractCredentials0(final SecurityRequest request) {
 
         } catch (WeakKeyException e) {
             log.error("Cannot authenticate user with JWT because of ", e);
+            return null;
         } catch (Exception e) {
             if (log.isDebugEnabled()) {
                 log.debug("Invalid or expired JWT token.", e);
@@ -211,17 +207,13 @@ private String extractJwtFromHeader(SecurityRequest request) {
             return null;
         }
 
-        if (!BEARER.matcher(jwtToken).matches()) {
-            return null;
-        }
-
-        if (jwtToken.toLowerCase().contains(BEARER_PREFIX)) {
-            jwtToken = jwtToken.substring(jwtToken.toLowerCase().indexOf(BEARER_PREFIX) + BEARER_PREFIX.length());
-        } else {
+        if (!BEARER.matcher(jwtToken).matches() || !jwtToken.toLowerCase().contains(BEARER_PREFIX)) {
             logDebug("No Bearer scheme found in header");
             return null;
         }
 
+        jwtToken = jwtToken.substring(jwtToken.toLowerCase().indexOf(BEARER_PREFIX) + BEARER_PREFIX.length());
+
         return jwtToken;
     }
 
diff --git a/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java b/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java
index aa8faa284d..03cbd20b42 100644
--- a/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java
+++ b/src/test/java/org/opensearch/security/authtoken/jwt/JwtVendorTest.java
@@ -15,8 +15,13 @@
 import org.apache.cxf.rs.security.jose.jwk.JsonWebKey;
 import org.apache.cxf.rs.security.jose.jws.JwsJwtCompactConsumer;
 import org.apache.cxf.rs.security.jose.jwt.JwtToken;
-import org.junit.Assert;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
 import org.junit.Test;
+import org.mockito.ArgumentCaptor;
 import org.opensearch.common.settings.Settings;
 import org.opensearch.security.support.ConfigConstants;
 
@@ -24,29 +29,74 @@
 import java.util.Optional;
 import java.util.function.LongSupplier;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
 public class JwtVendorTest {
+    private Appender mockAppender;
+    private ArgumentCaptor<LogEvent> logEventCaptor;
+
+    @Test
+    public void testCreateJwkFromSettingsThrowsException() {
+        Settings faultySettings = Settings.builder().put("key.someProperty", "badValue").build();
+
+        Exception thrownException = assertThrows(Exception.class, () -> new JwtVendor(faultySettings, null));
+
+        String expectedMessagePart = "An error occurred during the creation of Jwk: ";
+        assertTrue(thrownException.getMessage().contains(expectedMessagePart));
+    }
+
+    @Test
+    public void testJsonWebKeyPropertiesSetFromJwkSettings() throws Exception {
+        Settings settings = Settings.builder().put("jwt.key.key1", "value1").put("jwt.key.key2", "value2").build();
+
+        JsonWebKey jwk = JwtVendor.createJwkFromSettings(settings);
+
+        assertEquals("value1", jwk.getProperty("key1"));
+        assertEquals("value2", jwk.getProperty("key2"));
+    }
+
+    @Test
+    public void testJsonWebKeyPropertiesSetFromSettings() {
+        Settings jwkSettings = Settings.builder().put("key1", "value1").put("key2", "value2").build();
+
+        JsonWebKey jwk = new JsonWebKey();
+        for (String key : jwkSettings.keySet()) {
+            jwk.setProperty(key, jwkSettings.get(key));
+        }
+
+        assertEquals("value1", jwk.getProperty("key1"));
+        assertEquals("value2", jwk.getProperty("key2"));
+    }
 
     @Test
     public void testCreateJwkFromSettings() throws Exception {
         Settings settings = Settings.builder().put("signing_key", "abc123").build();
 
         JsonWebKey jwk = JwtVendor.createJwkFromSettings(settings);
-        Assert.assertEquals("HS512", jwk.getAlgorithm());
-        Assert.assertEquals("sig", jwk.getPublicKeyUse().toString());
-        Assert.assertEquals("abc123", jwk.getProperty("k"));
+        assertEquals("HS512", jwk.getAlgorithm());
+        assertEquals("sig", jwk.getPublicKeyUse().toString());
+        assertEquals("abc123", jwk.getProperty("k"));
     }
 
     @Test
     public void testCreateJwkFromSettingsWithoutSigningKey() {
         Settings settings = Settings.builder().put("jwt", "").build();
-        Throwable exception = Assert.assertThrows(RuntimeException.class, () -> {
+        Throwable exception = assertThrows(RuntimeException.class, () -> {
             try {
                 JwtVendor.createJwkFromSettings(settings);
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
         });
-        Assert.assertEquals(
+        assertEquals(
             "java.lang.Exception: Settings for signing key is missing. Please specify at least the option signing_key with a shared secret.",
             exception.getMessage()
         );
@@ -72,15 +122,15 @@ public void testCreateJwtWithRoles() throws Exception {
         JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(encodedJwt);
         JwtToken jwt = jwtConsumer.getJwtToken();
 
-        Assert.assertEquals("cluster_0", jwt.getClaim("iss"));
-        Assert.assertEquals("admin", jwt.getClaim("sub"));
-        Assert.assertEquals("audience_0", jwt.getClaim("aud"));
-        Assert.assertNotNull(jwt.getClaim("iat"));
-        Assert.assertNotNull(jwt.getClaim("exp"));
-        Assert.assertEquals(expectedExp, jwt.getClaim("exp"));
+        assertEquals("cluster_0", jwt.getClaim("iss"));
+        assertEquals("admin", jwt.getClaim("sub"));
+        assertEquals("audience_0", jwt.getClaim("aud"));
+        assertNotNull(jwt.getClaim("iat"));
+        assertNotNull(jwt.getClaim("exp"));
+        assertEquals(expectedExp, jwt.getClaim("exp"));
         EncryptionDecryptionUtil encryptionUtil = new EncryptionDecryptionUtil(claimsEncryptionKey);
-        Assert.assertEquals(expectedRoles, encryptionUtil.decrypt(jwt.getClaim("er").toString()));
-        Assert.assertNull(jwt.getClaim("br"));
+        assertEquals(expectedRoles, encryptionUtil.decrypt(jwt.getClaim("er").toString()));
+        assertNull(jwt.getClaim("br"));
     }
 
     @Test
@@ -111,20 +161,20 @@ public void testCreateJwtWithRoleSecurityMode() throws Exception {
         JwsJwtCompactConsumer jwtConsumer = new JwsJwtCompactConsumer(encodedJwt);
         JwtToken jwt = jwtConsumer.getJwtToken();
 
-        Assert.assertEquals("cluster_0", jwt.getClaim("iss"));
-        Assert.assertEquals("admin", jwt.getClaim("sub"));
-        Assert.assertEquals("audience_0", jwt.getClaim("aud"));
-        Assert.assertNotNull(jwt.getClaim("iat"));
-        Assert.assertNotNull(jwt.getClaim("exp"));
-        Assert.assertEquals(expectedExp, jwt.getClaim("exp"));
+        assertEquals("cluster_0", jwt.getClaim("iss"));
+        assertEquals("admin", jwt.getClaim("sub"));
+        assertEquals("audience_0", jwt.getClaim("aud"));
+        assertNotNull(jwt.getClaim("iat"));
+        assertNotNull(jwt.getClaim("exp"));
+        assertEquals(expectedExp, jwt.getClaim("exp"));
         EncryptionDecryptionUtil encryptionUtil = new EncryptionDecryptionUtil(claimsEncryptionKey);
-        Assert.assertEquals(expectedRoles, encryptionUtil.decrypt(jwt.getClaim("er").toString()));
-        Assert.assertNotNull(jwt.getClaim("br"));
-        Assert.assertEquals(expectedBackendRoles, jwt.getClaim("br"));
+        assertEquals(expectedRoles, encryptionUtil.decrypt(jwt.getClaim("er").toString()));
+        assertNotNull(jwt.getClaim("br"));
+        assertEquals(expectedBackendRoles, jwt.getClaim("br"));
     }
 
     @Test
-    public void testCreateJwtWithBadExpiry() {
+    public void testCreateJwtWithNegativeExpiry() {
         String issuer = "cluster_0";
         String subject = "admin";
         String audience = "audience_0";
@@ -134,14 +184,40 @@ public void testCreateJwtWithBadExpiry() {
         Settings settings = Settings.builder().put("signing_key", "abc123").put("encryption_key", claimsEncryptionKey).build();
         JwtVendor jwtVendor = new JwtVendor(settings, Optional.empty());
 
-        Throwable exception = Assert.assertThrows(RuntimeException.class, () -> {
+        Throwable exception = assertThrows(RuntimeException.class, () -> {
             try {
                 jwtVendor.createJwt(issuer, subject, audience, expirySeconds, roles, List.of(), true);
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
         });
-        Assert.assertEquals("java.lang.Exception: The expiration time should be a positive integer", exception.getMessage());
+        assertEquals("java.lang.Exception: The expiration time should be a positive integer", exception.getMessage());
+    }
+
+    @Test
+    public void testCreateJwtWithExceededExpiry() throws Exception {
+        String issuer = "cluster_0";
+        String subject = "admin";
+        String audience = "audience_0";
+        List<String> roles = List.of("IT", "HR");
+        List<String> backendRoles = List.of("Sales", "Support");
+        int expirySeconds = 900;
+        LongSupplier currentTime = () -> (long) 100;
+        String claimsEncryptionKey = RandomStringUtils.randomAlphanumeric(16);
+        Settings settings = Settings.builder().put("signing_key", "abc123").put("encryption_key", claimsEncryptionKey).build();
+        JwtVendor jwtVendor = new JwtVendor(settings, Optional.of(currentTime));
+
+        Throwable exception = assertThrows(RuntimeException.class, () -> {
+            try {
+                jwtVendor.createJwt(issuer, subject, audience, expirySeconds, roles, backendRoles, true);
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+        });
+        assertEquals(
+            "java.lang.Exception: The provided expiration time exceeds the maximum allowed duration of 600 seconds",
+            exception.getMessage()
+        );
     }
 
     @Test
@@ -154,14 +230,14 @@ public void testCreateJwtWithBadEncryptionKey() {
 
         Settings settings = Settings.builder().put("signing_key", "abc123").build();
 
-        Throwable exception = Assert.assertThrows(RuntimeException.class, () -> {
+        Throwable exception = assertThrows(RuntimeException.class, () -> {
             try {
                 new JwtVendor(settings, Optional.empty()).createJwt(issuer, subject, audience, expirySeconds, roles, List.of(), true);
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
         });
-        Assert.assertEquals("java.lang.IllegalArgumentException: encryption_key cannot be null", exception.getMessage());
+        assertEquals("java.lang.IllegalArgumentException: encryption_key cannot be null", exception.getMessage());
     }
 
     @Test
@@ -175,13 +251,49 @@ public void testCreateJwtWithBadRoles() {
         Settings settings = Settings.builder().put("signing_key", "abc123").put("encryption_key", claimsEncryptionKey).build();
         JwtVendor jwtVendor = new JwtVendor(settings, Optional.empty());
 
-        Throwable exception = Assert.assertThrows(RuntimeException.class, () -> {
+        Throwable exception = assertThrows(RuntimeException.class, () -> {
             try {
                 jwtVendor.createJwt(issuer, subject, audience, expirySeconds, roles, List.of(), true);
             } catch (Exception e) {
                 throw new RuntimeException(e);
             }
         });
-        Assert.assertEquals("java.lang.Exception: Roles cannot be null", exception.getMessage());
+        assertEquals("java.lang.Exception: Roles cannot be null", exception.getMessage());
+    }
+
+    @Test
+    public void testCreateJwtLogsCorrectly() throws Exception {
+        mockAppender = mock(Appender.class);
+        logEventCaptor = ArgumentCaptor.forClass(LogEvent.class);
+        when(mockAppender.getName()).thenReturn("MockAppender");
+        when(mockAppender.isStarted()).thenReturn(true);
+        Logger logger = (Logger) LogManager.getLogger(JwtVendor.class);
+        logger.addAppender(mockAppender);
+        logger.setLevel(Level.DEBUG);
+
+        // Mock settings and other required dependencies
+        LongSupplier currentTime = () -> (long) 100;
+        String claimsEncryptionKey = RandomStringUtils.randomAlphanumeric(16);
+        Settings settings = Settings.builder().put("signing_key", "abc123").put("encryption_key", claimsEncryptionKey).build();
+
+        String issuer = "cluster_0";
+        String subject = "admin";
+        String audience = "audience_0";
+        List<String> roles = List.of("IT", "HR");
+        List<String> backendRoles = List.of("Sales", "Support");
+        int expirySeconds = 300;
+
+        JwtVendor jwtVendor = new JwtVendor(settings, Optional.of(currentTime));
+
+        jwtVendor.createJwt(issuer, subject, audience, expirySeconds, roles, backendRoles, false);
+
+        verify(mockAppender, times(1)).append(logEventCaptor.capture());
+
+        LogEvent logEvent = logEventCaptor.getValue();
+        String logMessage = logEvent.getMessage().getFormattedMessage();
+        assertTrue(logMessage.startsWith("Created JWT:"));
+
+        String[] parts = logMessage.split("\\.");
+        assertTrue(parts.length >= 3);
     }
 }
diff --git a/src/test/java/org/opensearch/security/http/OnBehalfOfAuthenticatorTest.java b/src/test/java/org/opensearch/security/http/OnBehalfOfAuthenticatorTest.java
index 1ff6adee3a..b32792190f 100644
--- a/src/test/java/org/opensearch/security/http/OnBehalfOfAuthenticatorTest.java
+++ b/src/test/java/org/opensearch/security/http/OnBehalfOfAuthenticatorTest.java
@@ -11,30 +11,64 @@
 
 package org.opensearch.security.http;
 
+import java.lang.reflect.Field;
 import java.nio.charset.StandardCharsets;
 import java.util.Base64;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
+import java.util.List;
+import java.util.HashSet;
+import java.util.Arrays;
+import java.util.Optional;
 
 import javax.crypto.SecretKey;
 
 import com.google.common.io.BaseEncoding;
 import io.jsonwebtoken.JwtBuilder;
+import io.jsonwebtoken.JwtParser;
 import io.jsonwebtoken.Jwts;
 import io.jsonwebtoken.SignatureAlgorithm;
 import io.jsonwebtoken.security.Keys;
+import io.jsonwebtoken.security.WeakKeyException;
 import org.apache.commons.lang3.RandomStringUtils;
 import org.apache.hc.core5.http.HttpHeaders;
-import org.junit.Assert;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.ErrorHandler;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.Logger;
 import org.junit.Test;
 
+import org.mockito.ArgumentCaptor;
+import org.opensearch.SpecialPermission;
 import org.opensearch.common.settings.Settings;
+import org.opensearch.security.authtoken.jwt.EncryptionDecryptionUtil;
+import org.opensearch.security.filter.SecurityRequest;
+import org.opensearch.security.filter.SecurityResponse;
 import org.opensearch.security.user.AuthCredentials;
 import org.opensearch.security.util.FakeRestRequest;
 
 import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.opensearch.rest.RestRequest.Method.POST;
+import static org.opensearch.rest.RestRequest.Method.PUT;
 
 public class OnBehalfOfAuthenticatorTest {
     final static String clusterName = "cluster_0";
@@ -47,9 +81,27 @@ public class OnBehalfOfAuthenticatorTest {
     final static String signingKeyB64Encoded = BaseEncoding.base64().encode(signingKey.getBytes(StandardCharsets.UTF_8));
     final static SecretKey secretKey = Keys.hmacShaKeyFor(signingKeyB64Encoded.getBytes(StandardCharsets.UTF_8));
 
+    private static final String SECURITY_PREFIX = "/_plugins/_security/";
+    private static final String ON_BEHALF_OF_SUFFIX = "api/generateonbehalfoftoken";
+    private static final String ACCOUNT_SUFFIX = "api/account";
+
+    @Test
+    public void testReRequestAuthenticationReturnsEmptyOptional() {
+        OnBehalfOfAuthenticator authenticator = new OnBehalfOfAuthenticator(defaultSettings(), clusterName);
+        Optional<SecurityResponse> result = authenticator.reRequestAuthentication(null, null);
+        assertFalse(result.isPresent());
+    }
+
+    @Test
+    public void testGetTypeReturnsExpectedType() {
+        OnBehalfOfAuthenticator authenticator = new OnBehalfOfAuthenticator(defaultSettings(), clusterName);
+        String type = authenticator.getType();
+        assertEquals("onbehalfof_jwt", type);
+    }
+
     @Test
     public void testNoKey() {
-        Exception exception = Assert.assertThrows(
+        Exception exception = assertThrows(
             RuntimeException.class,
             () -> extractCredentialsFromJwtHeader(
                 null,
@@ -58,12 +110,12 @@ public void testNoKey() {
                 false
             )
         );
-        Assert.assertTrue(exception.getMessage().contains("Unable to find on behalf of authenticator signing key"));
+        assertTrue(exception.getMessage().contains("Unable to find on behalf of authenticator signing key"));
     }
 
     @Test
     public void testEmptyKey() {
-        Exception exception = Assert.assertThrows(
+        Exception exception = assertThrows(
             RuntimeException.class,
             () -> extractCredentialsFromJwtHeader(
                 null,
@@ -72,12 +124,12 @@ public void testEmptyKey() {
                 false
             )
         );
-        Assert.assertTrue(exception.getMessage().contains("Unable to find on behalf of authenticator signing key"));
+        assertTrue(exception.getMessage().contains("Unable to find on behalf of authenticator signing key"));
     }
 
     @Test
     public void testBadKey() {
-        Exception exception = Assert.assertThrows(
+        Exception exception = assertThrows(
             RuntimeException.class,
             () -> extractCredentialsFromJwtHeader(
                 BaseEncoding.base64().encode(new byte[] { 1, 3, 3, 4, 3, 6, 7, 8, 3, 10 }),
@@ -86,7 +138,45 @@ public void testBadKey() {
                 false
             )
         );
-        Assert.assertTrue(exception.getMessage().contains("The specified key byte array is 80 bits"));
+        assertTrue(exception.getMessage().contains("The specified key byte array is 80 bits"));
+    }
+
+    @Test
+    public void testWeakKeyExceptionHandling() throws Exception {
+        Appender mockAppender = mock(Appender.class);
+        ErrorHandler mockErrorHandler = mock(ErrorHandler.class);
+        when(mockAppender.getHandler()).thenReturn(mockErrorHandler);
+        when(mockAppender.isStarted()).thenReturn(true);
+
+        ArgumentCaptor<LogEvent> logEventCaptor = ArgumentCaptor.forClass(LogEvent.class);
+        when(mockAppender.getName()).thenReturn("MockAppender");
+        doNothing().when(mockAppender).append(logEventCaptor.capture());
+
+        Logger logger = (Logger) LogManager.getLogger(OnBehalfOfAuthenticator.class);
+        logger.addAppender(mockAppender);
+
+        JwtParser mockJwtParser = mock(JwtParser.class);
+        when(mockJwtParser.parseClaimsJws(anyString())).thenThrow(new WeakKeyException("Test Exception"));
+
+        Settings settings = Settings.builder().put("signing_key", "testKey").put("encryption_key", claimsEncryptionKey).build();
+        OnBehalfOfAuthenticator auth = new OnBehalfOfAuthenticator(settings, "testCluster");
+
+        Field jwtParserField = OnBehalfOfAuthenticator.class.getDeclaredField("jwtParser");
+        jwtParserField.setAccessible(true);
+        jwtParserField.set(auth, mockJwtParser);
+
+        SecurityRequest mockedRequest = mock(SecurityRequest.class);
+        when(mockedRequest.header(anyString())).thenReturn("Bearer testToken");
+        when(mockedRequest.path()).thenReturn("/some/sample/path");
+
+        auth.extractCredentials(mockedRequest, null);
+
+        boolean foundLog = logEventCaptor.getAllValues()
+            .stream()
+            .anyMatch(event -> event.getMessage().getFormattedMessage().contains("Cannot authenticate user with JWT because of "));
+        assertTrue(foundLog);
+
+        logger.removeAppender(mockAppender);
     }
 
     @Test
@@ -100,7 +190,7 @@ public void testTokenMissing() throws Exception {
             null
         );
 
-        Assert.assertNull(credentials);
+        assertNull(credentials);
     }
 
     @Test
@@ -116,7 +206,7 @@ public void testInvalid() throws Exception {
             new FakeRestRequest(headers, new HashMap<String, String>()).asSecurityRequest(),
             null
         );
-        Assert.assertNull(credentials);
+        assertNull(credentials);
     }
 
     @Test
@@ -136,7 +226,40 @@ public void testDisabled() throws Exception {
             new FakeRestRequest(headers, new HashMap<String, String>()).asSecurityRequest(),
             null
         );
-        Assert.assertNull(credentials);
+        assertNull(credentials);
+    }
+
+    @Test
+    public void testInvalidTokenException() {
+        Appender mockAppender = mock(Appender.class);
+        ArgumentCaptor<LogEvent> logEventCaptor = ArgumentCaptor.forClass(LogEvent.class);
+        when(mockAppender.getName()).thenReturn("MockAppender");
+        when(mockAppender.isStarted()).thenReturn(true);
+        Logger logger = (Logger) LogManager.getLogger(OnBehalfOfAuthenticator.class);
+        logger.addAppender(mockAppender);
+        logger.setLevel(Level.DEBUG);
+        doNothing().when(mockAppender).append(logEventCaptor.capture());
+
+        String invalidToken = "invalidToken";
+        Settings settings = defaultSettings();
+
+        OnBehalfOfAuthenticator jwtAuth = new OnBehalfOfAuthenticator(settings, clusterName);
+
+        Map<String, String> headers = Collections.singletonMap(HttpHeaders.AUTHORIZATION, "Bearer " + invalidToken);
+
+        AuthCredentials credentials = jwtAuth.extractCredentials(
+            new FakeRestRequest(headers, Collections.emptyMap()).asSecurityRequest(),
+            null
+        );
+
+        assertNull(credentials);
+
+        boolean foundLog = logEventCaptor.getAllValues()
+            .stream()
+            .anyMatch(event -> event.getMessage().getFormattedMessage().contains("Invalid or expired JWT token."));
+        assertTrue(foundLog);
+
+        logger.removeAppender(mockAppender);
     }
 
     @Test
@@ -156,7 +279,7 @@ public void testNonSpecifyOBOSetting() throws Exception {
             new FakeRestRequest(headers, new HashMap<String, String>()).asSecurityRequest(),
             null
         );
-        Assert.assertNotNull(credentials);
+        assertNotNull(credentials);
     }
 
     @Test
@@ -182,11 +305,11 @@ public void testBearer() throws Exception {
             null
         );
 
-        Assert.assertNotNull(credentials);
-        Assert.assertEquals("Leonard McCoy", credentials.getUsername());
-        Assert.assertEquals(0, credentials.getSecurityRoles().size());
-        Assert.assertEquals(0, credentials.getBackendRoles().size());
-        Assert.assertThat(credentials.getAttributes(), equalTo(expectedAttributes));
+        assertNotNull(credentials);
+        assertEquals("Leonard McCoy", credentials.getUsername());
+        assertEquals(0, credentials.getSecurityRoles().size());
+        assertEquals(0, credentials.getBackendRoles().size());
+        assertThat(credentials.getAttributes(), equalTo(expectedAttributes));
     }
 
     @Test
@@ -208,7 +331,25 @@ public void testBearerWrongPosition() throws Exception {
             null
         );
 
-        Assert.assertNull(credentials);
+        assertNull(credentials);
+    }
+
+    @Test
+    public void testSecurityManagerCheck() {
+        SecurityManager mockSecurityManager = mock(SecurityManager.class);
+        System.setSecurityManager(mockSecurityManager);
+
+        OnBehalfOfAuthenticator jwtAuth = new OnBehalfOfAuthenticator(defaultSettings(), clusterName);
+        Map<String, String> headers = new HashMap<>();
+        headers.put("Authorization", "Bearer someToken");
+
+        try {
+            jwtAuth.extractCredentials(new FakeRestRequest(headers, new HashMap<>()).asSecurityRequest(), null);
+        } finally {
+            System.setSecurityManager(null);
+        }
+
+        verify(mockSecurityManager, times(2)).checkPermission(any(SpecialPermission.class));
     }
 
     @Test
@@ -227,11 +368,63 @@ public void testBasicAuthHeader() throws Exception {
             new FakeRestRequest(headers, Collections.emptyMap()).asSecurityRequest(),
             null
         );
-        Assert.assertNull(credentials);
+        assertNull(credentials);
+    }
+
+    @Test
+    public void testMissingBearerScheme() throws Exception {
+        Appender mockAppender = mock(Appender.class);
+        ArgumentCaptor<LogEvent> logEventCaptor = ArgumentCaptor.forClass(LogEvent.class);
+        when(mockAppender.getName()).thenReturn("MockAppender");
+        when(mockAppender.isStarted()).thenReturn(true);
+        Logger logger = (Logger) LogManager.getLogger(OnBehalfOfAuthenticator.class);
+        logger.addAppender(mockAppender);
+        logger.setLevel(Level.DEBUG);
+        doNothing().when(mockAppender).append(logEventCaptor.capture());
+
+        String craftedToken = "beaRerSomeActualToken"; // This token matches the BEARER pattern but doesn't contain the BEARER_PREFIX
+
+        OnBehalfOfAuthenticator jwtAuth = new OnBehalfOfAuthenticator(defaultSettings(), clusterName);
+        Map<String, String> headers = Collections.singletonMap(HttpHeaders.AUTHORIZATION, craftedToken);
+
+        AuthCredentials credentials = jwtAuth.extractCredentials(
+            new FakeRestRequest(headers, Collections.emptyMap()).asSecurityRequest(),
+            null
+        );
+
+        assertNull(credentials);
+
+        boolean foundLog = logEventCaptor.getAllValues()
+            .stream()
+            .anyMatch(event -> event.getMessage().getFormattedMessage().contains("No Bearer scheme found in header"));
+        assertTrue(foundLog);
+
+        logger.removeAppender(mockAppender);
+    }
+
+    @Test
+    public void testMissingBearerPrefixInAuthHeader() {
+        String jwsToken = Jwts.builder()
+            .setIssuer(clusterName)
+            .setSubject("Leonard McCoy")
+            .setAudience("ext_0")
+            .signWith(secretKey, SignatureAlgorithm.HS512)
+            .compact();
+
+        OnBehalfOfAuthenticator jwtAuth = new OnBehalfOfAuthenticator(defaultSettings(), clusterName);
+
+        Map<String, String> headers = Collections.singletonMap(HttpHeaders.AUTHORIZATION, jwsToken);
+
+        AuthCredentials credentials = jwtAuth.extractCredentials(
+            new FakeRestRequest(headers, Collections.emptyMap()).asSecurityRequest(),
+            null
+        );
+
+        assertNull(credentials);
     }
 
     @Test
-    public void testRoles() throws Exception {
+    public void testPlainTextedRolesFromDrClaim() {
 
         final AuthCredentials credentials = extractCredentialsFromJwtHeader(
             signingKeyB64Encoded,
@@ -240,10 +433,46 @@ public void testRoles() throws Exception {
             true
         );
 
-        Assert.assertNotNull(credentials);
-        Assert.assertEquals("Leonard McCoy", credentials.getUsername());
-        Assert.assertEquals(2, credentials.getSecurityRoles().size());
-        Assert.assertEquals(0, credentials.getBackendRoles().size());
+        assertNotNull(credentials);
+        assertEquals("Leonard McCoy", credentials.getUsername());
+        assertEquals(2, credentials.getSecurityRoles().size());
+        assertEquals(0, credentials.getBackendRoles().size());
+    }
+
+    @Test
+    public void testBackendRolesExtraction() {
+        String rolesString = "role1, role2 ,role3,role4 , role5";
+
+        final AuthCredentials credentials = extractCredentialsFromJwtHeader(
+            signingKeyB64Encoded,
+            claimsEncryptionKey,
+            Jwts.builder().setIssuer(clusterName).setSubject("Test User").setAudience("audience_0").claim("br", rolesString),
+            true
+        );
+
+        assertNotNull(credentials);
+
+        Set<String> expectedBackendRoles = new HashSet<>(Arrays.asList("role1", "role2", "role3", "role4", "role5"));
+        Set<String> actualBackendRoles = credentials.getBackendRoles();
+
+        assertTrue(actualBackendRoles.containsAll(expectedBackendRoles));
+    }
+
+    @Test
+    public void testRolesDecryptionFromErClaim() {
+        EncryptionDecryptionUtil util = new EncryptionDecryptionUtil(claimsEncryptionKey);
+        String encryptedRole = util.encrypt("admin,developer");
+
+        final AuthCredentials credentials = extractCredentialsFromJwtHeader(
+            signingKeyB64Encoded,
+            claimsEncryptionKey,
+            Jwts.builder().setIssuer(clusterName).setSubject("Test User").setAudience("audience_0").claim("er", encryptedRole),
+            true
+        );
+
+        assertNotNull(credentials);
+        List<String> expectedRoles = Arrays.asList("admin", "developer");
+        assertTrue(credentials.getSecurityRoles().containsAll(expectedRoles));
     }
 
     @Test
@@ -256,9 +485,9 @@ public void testNullClaim() throws Exception {
             false
         );
 
-        Assert.assertNotNull(credentials);
-        Assert.assertEquals("Leonard McCoy", credentials.getUsername());
-        Assert.assertEquals(0, credentials.getBackendRoles().size());
+        assertNotNull(credentials);
+        assertEquals("Leonard McCoy", credentials.getUsername());
+        assertEquals(0, credentials.getBackendRoles().size());
     }
 
     @Test
@@ -271,10 +500,10 @@ public void testNonStringClaim() throws Exception {
             true
         );
 
-        Assert.assertNotNull(credentials);
-        Assert.assertEquals("Leonard McCoy", credentials.getUsername());
-        Assert.assertEquals(1, credentials.getSecurityRoles().size());
-        Assert.assertTrue(credentials.getSecurityRoles().contains("123"));
+        assertNotNull(credentials);
+        assertEquals("Leonard McCoy", credentials.getUsername());
+        assertEquals(1, credentials.getSecurityRoles().size());
+        assertTrue(credentials.getSecurityRoles().contains("123"));
     }
 
     @Test
@@ -287,10 +516,10 @@ public void testRolesMissing() throws Exception {
             false
         );
 
-        Assert.assertNotNull(credentials);
-        Assert.assertEquals("Leonard McCoy", credentials.getUsername());
-        Assert.assertEquals(0, credentials.getSecurityRoles().size());
-        Assert.assertEquals(0, credentials.getBackendRoles().size());
+        assertNotNull(credentials);
+        assertEquals("Leonard McCoy", credentials.getUsername());
+        assertEquals(0, credentials.getSecurityRoles().size());
+        assertEquals(0, credentials.getBackendRoles().size());
     }
 
     @Test
@@ -303,7 +532,20 @@ public void testWrongSubjectKey() throws Exception {
             false
         );
 
-        Assert.assertNull(credentials);
+        assertNull(credentials);
+    }
+
+    @Test
+    public void testMissingAudienceClaim() throws Exception {
+
+        final AuthCredentials credentials = extractCredentialsFromJwtHeader(
+            signingKeyB64Encoded,
+            claimsEncryptionKey,
+            Jwts.builder().setIssuer(clusterName).setSubject("Test User").claim("roles", "role1,role2"),
+            false
+        );
+
+        assertNull(credentials);
     }
 
     @Test
@@ -316,7 +558,7 @@ public void testExp() throws Exception {
             false
         );
 
-        Assert.assertNull(credentials);
+        assertNull(credentials);
     }
 
     @Test
@@ -329,7 +571,7 @@ public void testNbf() throws Exception {
             false
         );
 
-        Assert.assertNull(credentials);
+        assertNull(credentials);
     }
 
     @Test
@@ -348,12 +590,12 @@ public void testRolesArray() throws Exception {
 
         final AuthCredentials credentials = extractCredentialsFromJwtHeader(signingKeyB64Encoded, claimsEncryptionKey, builder, true);
 
-        Assert.assertNotNull(credentials);
-        Assert.assertEquals("Cluster_0", credentials.getUsername());
-        Assert.assertEquals(3, credentials.getSecurityRoles().size());
-        Assert.assertTrue(credentials.getSecurityRoles().contains("a"));
-        Assert.assertTrue(credentials.getSecurityRoles().contains("b"));
-        Assert.assertTrue(credentials.getSecurityRoles().contains("3rd"));
+        assertNotNull(credentials);
+        assertEquals("Cluster_0", credentials.getUsername());
+        assertEquals(3, credentials.getSecurityRoles().size());
+        assertTrue(credentials.getSecurityRoles().contains("a"));
+        assertTrue(credentials.getSecurityRoles().contains("b"));
+        assertTrue(credentials.getSecurityRoles().contains("3rd"));
     }
 
     @Test
@@ -375,7 +617,28 @@ public void testDifferentIssuer() throws Exception {
             null
         );
 
-        Assert.assertNull(credentials);
+        assertNull(credentials);
+    }
+
+    @Test
+    public void testRequestNotAllowed() {
+        OnBehalfOfAuthenticator oboAuth = new OnBehalfOfAuthenticator(defaultSettings(), clusterName);
+
+        // Test POST on generate on-behalf-of token endpoint
+        SecurityRequest mockedRequest1 = mock(SecurityRequest.class);
+        when(mockedRequest1.header(HttpHeaders.AUTHORIZATION)).thenReturn("Bearer someToken");
+        when(mockedRequest1.path()).thenReturn(SECURITY_PREFIX + ON_BEHALF_OF_SUFFIX);
+        when(mockedRequest1.method()).thenReturn(POST);
+        assertFalse(oboAuth.isRequestAllowed(mockedRequest1));
+        assertNull(oboAuth.extractCredentials(mockedRequest1, null));
+
+        // Test PUT on password changing endpoint
+        SecurityRequest mockedRequest2 = mock(SecurityRequest.class);
+        when(mockedRequest2.header(HttpHeaders.AUTHORIZATION)).thenReturn("Bearer someToken");
+        when(mockedRequest2.path()).thenReturn(SECURITY_PREFIX + ACCOUNT_SUFFIX);
+        when(mockedRequest2.method()).thenReturn(PUT);
+        assertFalse(oboAuth.isRequestAllowed(mockedRequest2));
+        assertNull(oboAuth.extractCredentials(mockedRequest2, null));
     }
 
     /** extracts a default user credential from a request header */
@@ -418,6 +681,10 @@ private Settings disableOBOSettings() {
             .build();
     }
 
+    private Settings noSigningKeyOBOSettings() {
+        return Settings.builder().put("enabled", disableOBO).put("encryption_key", claimsEncryptionKey).build();
+    }
+
     private Settings nonSpecifyOBOSetting() {
         return Settings.builder().put("signing_key", signingKeyB64Encoded).put("encryption_key", claimsEncryptionKey).build();
     }