Handle ClientData parsing errors in SessionCodeChecks gracefully
- Move ClientData parsing out of SessionCodeChecks ctor - Respond with a bad request if invalid client data is presented Closes #32515 Signed-off-by: Thomas Darimont <thomas.darimont@googlemail.com> Signed-off-by: Alexander Schwartz <aschwart@redhat.com> Co-authored-by: Alexander Schwartz <aschwart@redhat.com>
This commit is contained in:
parent
83a57892ea
commit
693a63b532
3 changed files with 24 additions and 17 deletions
|
@ -96,18 +96,13 @@ public class ClientData {
|
|||
return String.format("ClientData [ redirectUri=%s, responseType=%s, responseMode=%s, state=%s ]", redirectUri, responseType, responseMode, state);
|
||||
}
|
||||
|
||||
public static ClientData decodeClientDataFromParameter(String clientDataParam) {
|
||||
try {
|
||||
public static ClientData decodeClientDataFromParameter(String clientDataParam) throws IOException {
|
||||
if (ObjectUtil.isBlank(clientDataParam)) {
|
||||
return null;
|
||||
} else {
|
||||
byte[] cdataJson = Base64Url.decode(clientDataParam);
|
||||
return JsonSerialization.readValue(cdataJson, ClientData.class);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
logger.warnf("ClientData parameter in invalid format. ClientData parameter was %s", clientDataParam);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String encode() {
|
||||
|
|
|
@ -6,6 +6,8 @@ import org.keycloak.models.ClientModel;
|
|||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.protocol.ClientData;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class IdentityBrokerStateTest {
|
||||
|
||||
|
@ -48,7 +50,7 @@ public class IdentityBrokerStateTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testDecodedWithClientIdAnActualUuidBASE64UriFriendly() {
|
||||
public void testDecodedWithClientIdAnActualUuidBASE64UriFriendly() throws IOException {
|
||||
|
||||
// Given
|
||||
String state = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk";
|
||||
|
@ -90,7 +92,7 @@ public class IdentityBrokerStateTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testEncodedWithClientIdNotUUid() {
|
||||
public void testEncodedWithClientIdNotUUid() throws IOException {
|
||||
// Given
|
||||
String encoded = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk.vpISZLVDAc0.aHR0cDovL2kuYW0uYW4udXJs";
|
||||
String clientId = "http://i.am.an.url";
|
||||
|
@ -107,7 +109,7 @@ public class IdentityBrokerStateTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void testEncodedWithClientData() {
|
||||
public void testEncodedWithClientData() throws IOException {
|
||||
// Given
|
||||
String encoded = "gNrGamIDGKpKSI9yOrcFzYTKoFGH779_WNCacAelkhk.vpISZLVDAc0.aHR0cDovL2kuYW0uYW4udXJs.eyJydSI6Imh0dHBzOi8vbXktcmVkaXJlY3QtdXJpIiwicnQiOiJjb2RlIiwicm0iOiJxdWVyeSIsInN0Ijoic29tZS1zdGF0ZSJ9";
|
||||
String clientId = "http://i.am.an.url";
|
||||
|
|
|
@ -19,6 +19,7 @@ package org.keycloak.services.resources;
|
|||
|
||||
import static org.keycloak.services.managers.AuthenticationManager.authenticateIdentityCookie;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
import jakarta.ws.rs.core.Response;
|
||||
|
@ -42,8 +43,6 @@ import org.keycloak.protocol.AuthorizationEndpointBase;
|
|||
import org.keycloak.protocol.ClientData;
|
||||
import org.keycloak.protocol.LoginProtocol;
|
||||
import org.keycloak.protocol.RestartLoginCookie;
|
||||
import org.keycloak.protocol.oidc.endpoints.AuthorizationEndpointChecker;
|
||||
import org.keycloak.protocol.oidc.endpoints.request.AuthorizationEndpointRequest;
|
||||
import org.keycloak.services.ErrorPage;
|
||||
import org.keycloak.services.ServicesLogger;
|
||||
import org.keycloak.services.managers.AuthenticationManager;
|
||||
|
@ -76,7 +75,7 @@ public class SessionCodeChecks {
|
|||
private final String code;
|
||||
private final String execution;
|
||||
private final String clientId;
|
||||
private final ClientData clientData;
|
||||
private final String clientDataString;
|
||||
private final String tabId;
|
||||
private final String flowPath;
|
||||
private final String authSessionId;
|
||||
|
@ -97,7 +96,7 @@ public class SessionCodeChecks {
|
|||
this.tabId = tabId;
|
||||
this.flowPath = flowPath;
|
||||
this.authSessionId = authSessionId;
|
||||
this.clientData = ClientData.decodeClientDataFromParameter(clientData);
|
||||
this.clientDataString = clientData;
|
||||
}
|
||||
|
||||
|
||||
|
@ -174,6 +173,17 @@ public class SessionCodeChecks {
|
|||
|
||||
}
|
||||
|
||||
ClientData clientData;
|
||||
try {
|
||||
clientData = ClientData.decodeClientDataFromParameter(clientDataString);
|
||||
} catch (RuntimeException | IOException e) {
|
||||
logger.debugf(e, "ClientData parameter in invalid format. ClientData parameter was %s", clientDataString);
|
||||
event.detail(Details.REASON, "Invalid client data: " + e.getMessage());
|
||||
event.error(Errors.INVALID_REQUEST);
|
||||
response = ErrorPage.error(session, null, Response.Status.BAD_REQUEST, Messages.INVALID_REQUEST);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (authSession != null) {
|
||||
session.getProvider(LoginFormsProvider.class).setAuthenticationSession(authSession);
|
||||
return authSession;
|
||||
|
|
Loading…
Reference in a new issue