mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Stop looking up client in ClientAssertionState to prevent lookup by clientId in federated client authentication (#44448)
Closes #44447 Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
parent
570ac40025
commit
2acfd41b19
@ -21,8 +21,7 @@ public class ClientAssertionState {
|
||||
private final JWSInput jws;
|
||||
private final JsonWebToken token;
|
||||
|
||||
public ClientAssertionState(ClientModel client, String clientAssertionType, String clientAssertion, JWSInput jws, JsonWebToken token) {
|
||||
this.client = client;
|
||||
public ClientAssertionState(String clientAssertionType, String clientAssertion, JWSInput jws, JsonWebToken token) {
|
||||
this.clientAssertionType = clientAssertionType;
|
||||
this.clientAssertion = clientAssertion;
|
||||
this.jws = jws;
|
||||
@ -69,8 +68,6 @@ public class ClientAssertionState {
|
||||
JWSInput jws = null;
|
||||
JsonWebToken token = null;
|
||||
|
||||
ClientModel client = null;
|
||||
|
||||
if (clientAssertion != null) {
|
||||
jws = new JWSInput(clientAssertion);
|
||||
token = jws.readJsonContent(JsonWebToken.class);
|
||||
@ -79,13 +76,9 @@ public class ClientAssertionState {
|
||||
event.detail(Details.CLIENT_ASSERTION_ID, token.getId());
|
||||
event.detail(Details.CLIENT_ASSERTION_ISSUER, token.getIssuer());
|
||||
event.detail(Details.CLIENT_ASSERTION_SUB, token.getSubject());
|
||||
|
||||
if (token.getSubject() != null) {
|
||||
client = context.getRealm().getClientByClientId(token.getSubject());
|
||||
}
|
||||
}
|
||||
|
||||
return new ClientAssertionState(client, clientAssertionType, clientAssertion, jws, token);
|
||||
return new ClientAssertionState(clientAssertionType, clientAssertion, jws, token);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -84,6 +84,11 @@ public class FederatedJWTClientAuthenticator extends AbstractClientAuthenticator
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore for self-signed client assertions
|
||||
if (Objects.equals(clientAssertionState.getToken().getIssuer(), clientAssertionState.getToken().getSubject())) {
|
||||
return;
|
||||
}
|
||||
|
||||
ClientAssertionIdentityProviderFactory.ClientAssertionStrategy strategy = findStrategy(clientAssertionState.getClientAssertionType());
|
||||
if (strategy == null) {
|
||||
return;
|
||||
|
||||
@ -25,6 +25,7 @@ import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import jakarta.ws.rs.core.Response;
|
||||
@ -64,7 +65,20 @@ public class JWTClientAuthenticator extends AbstractClientAuthenticator {
|
||||
@Override
|
||||
public void authenticateClient(ClientAuthenticationFlowContext context) {
|
||||
try {
|
||||
ClientAssertionState clientAssertionState = context.getState(ClientAssertionState.class, ClientAssertionState.supplier());
|
||||
JsonWebToken jwt = clientAssertionState.getToken();
|
||||
|
||||
// Ignore for client assertions signed by third-parties
|
||||
if (!Objects.equals(jwt.getIssuer(), jwt.getSubject())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (clientAssertionState.getClient() == null) {
|
||||
clientAssertionState.setClient(context.getRealm().getClientByClientId(jwt.getSubject()));
|
||||
}
|
||||
|
||||
JWTClientValidator validator = new JWTClientValidator(context, this::verifySignature, getId());
|
||||
|
||||
if (!validator.validate()) return;
|
||||
|
||||
context.success();
|
||||
|
||||
@ -22,6 +22,7 @@ import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import jakarta.ws.rs.core.Response;
|
||||
@ -55,6 +56,18 @@ public class JWTClientSecretAuthenticator extends AbstractClientAuthenticator {
|
||||
@Override
|
||||
public void authenticateClient(ClientAuthenticationFlowContext context) {
|
||||
try {
|
||||
ClientAssertionState clientAssertionState = context.getState(ClientAssertionState.class, ClientAssertionState.supplier());
|
||||
JsonWebToken jwt = clientAssertionState.getToken();
|
||||
|
||||
// Ignore for client assertions signed by third-parties
|
||||
if (!Objects.equals(jwt.getIssuer(), jwt.getSubject())) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (clientAssertionState.getClient() == null) {
|
||||
clientAssertionState.setClient(context.getRealm().getClientByClientId(jwt.getSubject()));
|
||||
}
|
||||
|
||||
JWTClientValidator validator = new JWTClientValidator(context, this::verifySignature, getId());
|
||||
if (!validator.validate()) return;
|
||||
|
||||
|
||||
@ -51,7 +51,8 @@ public class JWTAuthorizationGrantValidator extends AbstractBaseJWTValidator imp
|
||||
try {
|
||||
JWSInput jws = new JWSInput(assertion);
|
||||
JsonWebToken jwt = jws.readJsonContent(JsonWebToken.class);
|
||||
ClientAssertionState clientAssertionState = new ClientAssertionState(client, OAuth2Constants.JWT_AUTHORIZATION_GRANT, assertion, jws, jwt);
|
||||
ClientAssertionState clientAssertionState = new ClientAssertionState(OAuth2Constants.JWT_AUTHORIZATION_GRANT, assertion, jws, jwt);
|
||||
clientAssertionState.setClient(client);
|
||||
return new JWTAuthorizationGrantValidator(session, scope, clientAssertionState);
|
||||
} catch (JWSInputException e) {
|
||||
throw new RuntimeException("The provided assertion is not a valid JWT");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user