Repository: apache/kafka
File: clients/src/test/java/org/apache/kafka/common/security/oauthbearer/ClientJwtValidatorTest.java (Java)

Code before:
import org.apache.kafka.common.utils.Utils;

import org.junit.jupiter.api.Test;

import java.util.Base64;

import static org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule.OAUTHBEARER_MECHANISM;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class ClientJwtValidatorTest extends JwtValidatorTest {

    @Override
    protected JwtValidator createJwtValidator(AccessTokenBuilder builder) {
        return new ClientJwtValidator();
    }

    @Test
    void testJwtRequiresBase64UrlDecoding() throws Exception {
        String header = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
        String payload = "{\"sub\": \"jdoe\", \"exp\": 0, \"iat\": 0, \"data\":\">>>___<<<---\"}";
        String signature = "dummysignature";
        String jwt = createJwt(header, payload, signature);

        // Verify that decoding the payload fails for "plain" base 64, but works with URL-safe base 64.
        String urlEndodedPayload = Base64.getUrlEncoder().encodeToString(Utils.utf8(payload));
        assertThrows(IllegalArgumentException.class, () -> Base64.getDecoder().decode(urlEndodedPayload));
        assertDoesNotThrow(() -> Base64.getUrlDecoder().decode(urlEndodedPayload));

        try (JwtValidator validator = createJwtValidator()) {
            validator.configure(getSaslConfigs(), OAUTHBEARER_MECHANISM, getJaasConfigEntries());
            validator.validate(jwt);
        }
    }
}


Review comment (suggestion):
```suggestion
        String urlEncodedPayload = Base64.getUrlEncoder().encodeToString(Utils.utf8(payload));
```

Code after:
import org.apache.kafka.common.utils.Utils;

import org.junit.jupiter.api.Test;

import java.util.Base64;

import static org.apache.kafka.common.security.oauthbearer.OAuthBearerLoginModule.OAUTHBEARER_MECHANISM;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class ClientJwtValidatorTest extends JwtValidatorTest {

    @Override
    protected JwtValidator createJwtValidator(AccessTokenBuilder builder) {
        return new ClientJwtValidator();
    }

    @Test
    void testJwtRequiresBase64UrlDecoding() throws Exception {
        String header = "{\"alg\":\"HS256\",\"typ\":\"JWT\"}";
        String payload = "{\"sub\": \"jdoe\", \"exp\": 0, \"iat\": 0, \"data\":\">>>___<<<---\"}";
        String signature = "dummysignature";
        String jwt = createJwt(header, payload, signature);

        // Verify that decoding the payload fails for "plain" base 64, but works with URL-safe base 64.
        String urlEncodedPayload = Base64.getUrlEncoder().encodeToString(Utils.utf8(payload));
        assertThrows(IllegalArgumentException.class, () -> Base64.getDecoder().decode(urlEncodedPayload));
        assertDoesNotThrow(() -> Base64.getUrlDecoder().decode(urlEncodedPayload));

        try (JwtValidator validator = createJwtValidator()) {
            validator.configure(getSaslConfigs(), OAUTHBEARER_MECHANISM, getJaasConfigEntries());
            assertDoesNotThrow(
                () -> validator.validate(jwt),
                "Valid, URL-safe base 64-encoded JWT should be decodable"
            );
        }
    }
}