Skip to content

Commit

Permalink
KAFKA-15077: Code to trim token in FileTokenRetriever (apache#13835)
Browse files Browse the repository at this point in the history
The FileTokenRetriever class is used to read the access_token from a file on the clients system and then it is passed along with the jaas config to the OAuthBearerSaslServer. In case the token was sent using FileTokenRetriever on the client side, some EOL character is getting appended to the token, causing authentication to fail with the message:


Reviewers: Manikumar Reddy <[email protected]>
  • Loading branch information
smjn authored Jun 11, 2023
1 parent daba741 commit 5afce2d
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public FileTokenRetriever(Path accessTokenFile) {
@Override
public void init() throws IOException {
this.accessToken = Utils.readFileAsString(accessTokenFile.toFile().getPath());
// always non-null; to remove any newline chars or backend will report err
this.accessToken = this.accessToken.trim();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

import java.io.File;
import java.io.IOException;
import java.util.Base64;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TimeZone;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.apache.kafka.common.config.ConfigException;
Expand Down Expand Up @@ -167,6 +170,32 @@ public void testMissingAccessToken() {
}
}

@Test
public void testFileTokenRetrieverHandlesNewline() throws IOException {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
long cur = cal.getTimeInMillis() / 1000;
String exp = "" + (cur + 60 * 60); // 1 hour in future
String iat = "" + cur;

String expected = createAccessKey("{}", String.format("{\"exp\":%s, \"iat\":%s, \"sub\":\"subj\"}", exp, iat), "sign");
String withNewline = expected + "\n";

File tmpDir = createTempDir("access-token");
File accessTokenFile = createTempFile(tmpDir, "access-token-", ".json", withNewline);

Map<String, ?> configs = getSaslConfigs();
OAuthBearerLoginCallbackHandler handler = createHandler(new FileTokenRetriever(accessTokenFile.toPath()), configs);
OAuthBearerTokenCallback callback = new OAuthBearerTokenCallback();
try {
handler.handle(new Callback[]{callback});
assertEquals(callback.token().value(), expected);
} catch (Exception e) {
fail(e);
} finally {
handler.close();
}
}

@Test
public void testNotConfigured() {
OAuthBearerLoginCallbackHandler handler = new OAuthBearerLoginCallbackHandler();
Expand Down

0 comments on commit 5afce2d

Please sign in to comment.