Skip to content
代码片段 群组 项目
未验证 提交 160a6ab4 编辑于 作者: Daniel Fonai's avatar Daniel Fonai 提交者: GitHub
浏览文件

KAFKA-13730: OAuth access token validation fails if it does not contain the "sub" claim (#11886)

Removes the requirement of presence of sub claim in JWT access tokens, when clients authenticate via OAuth.
This does not interfere with OAuth specifications and is to ensure wider compatibility with OAuth providers.
Unit test added.

Reviewers:  Kirk True <ktrue@confluent.io>, Viktor Somogyi-Vass <viktorsomogyi@gmail.com>,  Manikumar Reddy <manikumar.reddy@gmail.com>
上级 6ac58ac6
No related branches found
No related tags found
无相关合并请求
......@@ -131,7 +131,6 @@ public class ValidatorAccessTokenValidator implements AccessTokenValidator {
.setJwsAlgorithmConstraints(DISALLOW_NONE)
.setRequireExpirationTime()
.setRequireIssuedAt()
.setRequireSubject()
.setVerificationKeyResolver(verificationKeyResolver)
.build();
this.scopeClaimName = scopeClaimName;
......
......@@ -22,6 +22,9 @@ import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.io.IOException;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.kafka.common.utils.MockTime;
import org.apache.kafka.common.utils.Time;
import org.jose4j.jwk.PublicJsonWebKey;
......@@ -39,7 +42,7 @@ public class AccessTokenBuilder {
private String subject = "jdoe";
private final String subjectClaimName = ReservedClaimNames.SUBJECT;
private String subjectClaimName = ReservedClaimNames.SUBJECT;
private Object scope = "engineering";
......@@ -51,6 +54,8 @@ public class AccessTokenBuilder {
private PublicJsonWebKey jwk;
private final Map<String, String> customClaims = new HashMap<>();
public AccessTokenBuilder() {
this(new MockTime());
}
......@@ -87,6 +92,11 @@ public class AccessTokenBuilder {
return subjectClaimName;
}
public AccessTokenBuilder subjectClaimName(String subjectClaimName) {
this.subjectClaimName = subjectClaimName;
return this;
}
public Object scope() {
return scope;
}
......@@ -133,6 +143,14 @@ public class AccessTokenBuilder {
return this;
}
public AccessTokenBuilder addCustomClaim(String name, String value) {
String validatedName = ClaimValidationUtils.validateClaimNameOverride("claim name", name);
String validatedValue = ClaimValidationUtils.validateClaimNameOverride(validatedName, value);
customClaims.put(validatedName, validatedValue);
return this;
}
@SuppressWarnings("unchecked")
public String build() throws JoseException, IOException {
ObjectNode node = objectMapper.createObjectNode();
......@@ -162,6 +180,10 @@ public class AccessTokenBuilder {
if (expirationSeconds != null)
node.put(ReservedClaimNames.EXPIRATION_TIME, expirationSeconds);
for (Map.Entry<String, String> claim : customClaims.entrySet()) {
node.put(claim.getKey(), claim.getValue());
}
String json = objectMapper.writeValueAsString(node);
JsonWebSignature jws = new JsonWebSignature();
......
......@@ -59,6 +59,25 @@ public class ValidatorAccessTokenValidatorTest extends AccessTokenValidatorTest
"fake is an unknown, unsupported or unavailable alg algorithm");
}
@Test
public void testMissingSubShouldBeValid() throws Exception {
String subClaimName = "client_id";
String subject = "otherSub";
PublicJsonWebKey jwk = createRsaJwk();
AccessTokenBuilder tokenBuilder = new AccessTokenBuilder()
.jwk(jwk)
.alg(AlgorithmIdentifiers.RSA_USING_SHA256)
.addCustomClaim(subClaimName, subject)
.subjectClaimName(subClaimName)
.subject(null);
AccessTokenValidator validator = createAccessTokenValidator(tokenBuilder);
// Validation should succeed (e.g. signature verification) even if sub claim is missing
OAuthBearerToken token = validator.validate(tokenBuilder.build());
assertEquals(subject, token.principalName());
}
private void testEncryptionAlgorithm(PublicJsonWebKey jwk, String alg) throws Exception {
AccessTokenBuilder builder = new AccessTokenBuilder().jwk(jwk).alg(alg);
AccessTokenValidator validator = createAccessTokenValidator(builder);
......
0% 加载中 .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册