mirror of
https://github.com/keycloak/keycloak.git
synced 2026-05-26 13:50:48 +00:00
Enable configurable client_id parameter validation for federated client assertions (#48026)
Closes #48024 Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com>
This commit is contained in:
committed by
GitHub
parent
71e63e99dc
commit
3e8a1310d9
+8
-9
@@ -101,12 +101,6 @@ public abstract class AbstractJWTClientValidator extends AbstractBaseJWTValidato
|
||||
return failure("Token sub claim is required");
|
||||
}
|
||||
|
||||
String clientIdParam = context.getHttpRequest().getDecodedFormParameters().getFirst(OAuth2Constants.CLIENT_ID);
|
||||
if (clientIdParam != null && !clientIdParam.equals(clientId)) {
|
||||
logger.debug("client_id parameter does not match JWT subject");
|
||||
return failure("client_id parameter does not match sub claim");
|
||||
}
|
||||
|
||||
String expectedTokenIssuer = getExpectedTokenIssuer();
|
||||
if (expectedTokenIssuer != null && !expectedTokenIssuer.equals(token.getIssuer())) {
|
||||
return false;
|
||||
@@ -116,11 +110,16 @@ public abstract class AbstractJWTClientValidator extends AbstractBaseJWTValidato
|
||||
|
||||
if (client == null) {
|
||||
return failure(AuthenticationFlowError.CLIENT_NOT_FOUND);
|
||||
} else {
|
||||
context.getEvent().client(client.getClientId());
|
||||
context.setClient(client);
|
||||
}
|
||||
|
||||
String clientIdParam = context.getHttpRequest().getDecodedFormParameters().getFirst(OAuth2Constants.CLIENT_ID);
|
||||
if (clientIdParam != null && !clientIdParam.equals(client.getClientId())) {
|
||||
return failure("client_id parameter does not match authenticated client");
|
||||
}
|
||||
|
||||
context.getEvent().client(client.getClientId());
|
||||
context.setClient(client);
|
||||
|
||||
if (!client.isEnabled()) {
|
||||
return failure(AuthenticationFlowError.CLIENT_DISABLED);
|
||||
}
|
||||
|
||||
+25
@@ -18,6 +18,7 @@ import org.keycloak.testframework.realm.IdentityProviderBuilder;
|
||||
import org.keycloak.testframework.realm.ManagedRealm;
|
||||
import org.keycloak.testframework.realm.RealmBuilder;
|
||||
import org.keycloak.testframework.realm.RealmConfig;
|
||||
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
|
||||
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
@@ -72,6 +73,30 @@ public class KubernetesClientAuthTest extends AbstractBaseClientAuthTest {
|
||||
assertSuccess(internalClientId, jwt.getId(), expectedTokenIssuer, externalClientId, events.poll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidTokenWithClientId() {
|
||||
JsonWebToken jwt = createDefaultToken();
|
||||
String jws = getIdentityProvider().encodeToken(jwt);
|
||||
AccessTokenResponse response = oAuthClient.clientCredentialsGrantRequest()
|
||||
.client(INTERNAL_CLIENT_ID)
|
||||
.clientJwt(jws, getClientAssertionType())
|
||||
.send();
|
||||
assertSuccess(internalClientId, response);
|
||||
assertSuccess(internalClientId, jwt.getId(), expectedTokenIssuer, externalClientId, events.poll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWrongClientIdFailsValidation() {
|
||||
JsonWebToken jwt = createDefaultToken();
|
||||
String jws = getIdentityProvider().encodeToken(jwt);
|
||||
AccessTokenResponse response = oAuthClient.clientCredentialsGrantRequest()
|
||||
.client("completely-wrong-id")
|
||||
.clientJwt(jws, getClientAssertionType())
|
||||
.send();
|
||||
assertFailure(response);
|
||||
assertFailure("completely-wrong-id", expectedTokenIssuer, externalClientId, jwt.getId(), "client_not_found", events.poll());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReuse() {
|
||||
JsonWebToken jwt = createDefaultToken();
|
||||
|
||||
+3
@@ -148,6 +148,9 @@ public abstract class AbstractHttpPostRequest<T, R> {
|
||||
if (clientAssertion != null && clientAssertionType != null) {
|
||||
parameter("client_assertion_type", clientAssertionType);
|
||||
parameter("client_assertion", clientAssertion);
|
||||
if (this.clientId != null) {
|
||||
parameter("client_id", this.clientId);
|
||||
}
|
||||
} else if (tokenType != null && tokenValue != null) {
|
||||
header("Authorization", tokenType + " " + tokenValue);
|
||||
} else if (clientSecret != null) {
|
||||
|
||||
Reference in New Issue
Block a user