Remove clientSessionState and clientSessionHost fields on OAuthClient (#38033)

Closes #38023

Signed-off-by: stianst <stianst@gmail.com>
This commit is contained in:
Stian Thorgersen 2025-03-12 10:10:45 +01:00 committed by GitHub
parent e405def2af
commit 899eb976aa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 41 additions and 104 deletions

View file

@ -20,8 +20,6 @@ public abstract class AbstractOAuthClient<T> {
protected OAuthClientConfig config;
protected Map<String, String> customParameters;
protected String clientSessionState;
protected String clientSessionHost;
private final KeyManager keyManager = new KeyManager(this);
private final TokensManager tokensManager = new TokensManager(keyManager);
@ -254,14 +252,6 @@ public abstract class AbstractOAuthClient<T> {
return config.getRedirectUri();
}
String getClientSessionState() {
return clientSessionState;
}
String getClientSessionHost() {
return clientSessionHost;
}
Map<String, String> getCustomParameters() {
return customParameters;
}

View file

@ -38,14 +38,16 @@ public class AccessTokenRequest extends AbstractHttpPostRequest<AccessTokenReque
return this;
}
public AccessTokenRequest param(String name, String value) {
parameter(name, value);
return this;
}
protected void initRequest() {
parameter(OAuth2Constants.GRANT_TYPE, OAuth2Constants.AUTHORIZATION_CODE);
parameter(OAuth2Constants.CODE, code);
parameter(OAuth2Constants.REDIRECT_URI, client.getRedirectUri());
parameter(AdapterConstants.CLIENT_SESSION_STATE, client.getClientSessionState());
parameter(AdapterConstants.CLIENT_SESSION_HOST, client.getClientSessionHost());
}
@Override

View file

@ -40,9 +40,6 @@ public class PasswordGrantRequest extends AbstractHttpPostRequest<PasswordGrantR
parameter("password", password);
parameter("otp", otp);
parameter(AdapterConstants.CLIENT_SESSION_STATE, client.getClientSessionState());
parameter(AdapterConstants.CLIENT_SESSION_HOST, client.getClientSessionHost());
scope();
}

View file

@ -2,7 +2,6 @@ package org.keycloak.testsuite.util.oauth;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.keycloak.OAuth2Constants;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.util.TokenUtil;
import java.io.IOException;
@ -30,9 +29,6 @@ public class RefreshRequest extends AbstractHttpPostRequest<RefreshRequest, Acce
parameter(OAuth2Constants.GRANT_TYPE, OAuth2Constants.REFRESH_TOKEN);
parameter(OAuth2Constants.REFRESH_TOKEN, refreshToken);
scope(false);
parameter(AdapterConstants.CLIENT_SESSION_STATE, client.getClientSessionState());
parameter(AdapterConstants.CLIENT_SESSION_HOST, client.getClientSessionHost());
}
@Override

View file

@ -2,7 +2,6 @@ package org.keycloak.testsuite.util.oauth;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.keycloak.OAuth2Constants;
import org.keycloak.constants.AdapterConstants;
import java.io.IOException;
import java.util.Arrays;
@ -61,9 +60,6 @@ public class TokenExchangeRequest extends AbstractHttpPostRequest<TokenExchangeR
additionalParams.forEach(this::parameter);
}
parameter(AdapterConstants.CLIENT_SESSION_STATE, client.getClientSessionState());
parameter(AdapterConstants.CLIENT_SESSION_HOST, client.getClientSessionHost());
parameter(OAuth2Constants.SCOPE, client.config().getScope(false));
}

View file

@ -78,8 +78,6 @@ public class OAuthClient extends AbstractOAuthClient<OAuthClient> {
.postLogoutRedirectUri(APP_ROOT + "/auth")
.responseType(OAuth2Constants.CODE);
clientSessionState = null;
clientSessionHost = null;
customParameters = null;
}
@ -133,16 +131,6 @@ public class OAuthClient extends AbstractOAuthClient<OAuthClient> {
return this;
}
public OAuthClient clientSessionState(String client_session_state) {
this.clientSessionState = client_session_state;
return this;
}
public OAuthClient clientSessionHost(String client_session_host) {
this.clientSessionHost = client_session_host;
return this;
}
public OAuthClient responseType(String responseType) {
config.responseType(responseType);
return this;

View file

@ -51,7 +51,6 @@ public class RPInitiatedFrontChannelLogoutTest extends AbstractTestRealmKeycloak
rep.getAttributes().put(OIDCConfigAttributes.FRONT_CHANNEL_LOGOUT_URI, OAuthClient.APP_ROOT + "/admin/frontchannelLogout");
clients.get(rep.getId()).update(rep);
try {
oauth.clientSessionState("client-session");
oauth.doLogin("test-user@localhost", "password");
String code = oauth.parseLoginResponse().getCode();
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
@ -81,7 +80,6 @@ public class RPInitiatedFrontChannelLogoutTest extends AbstractTestRealmKeycloak
rep.getAttributes().put(OIDCConfigAttributes.FRONT_CHANNEL_LOGOUT_SESSION_REQUIRED, "false");
clients.get(rep.getId()).update(rep);
try {
oauth.clientSessionState("client-session");
oauth.doLogin("test-user@localhost", "password");
String code = oauth.parseLoginResponse().getCode();
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
@ -110,7 +108,6 @@ public class RPInitiatedFrontChannelLogoutTest extends AbstractTestRealmKeycloak
rep.getAttributes().put(OIDCConfigAttributes.FRONT_CHANNEL_LOGOUT_URI, OAuthClient.APP_ROOT + "/admin/frontchannelLogout");
clients.get(rep.getId()).update(rep);
try {
oauth.clientSessionState("client-session");
oauth.doLogin("test-user@localhost", "password");
String code = oauth.parseLoginResponse().getCode();
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
@ -142,7 +139,6 @@ public class RPInitiatedFrontChannelLogoutTest extends AbstractTestRealmKeycloak
.setFrontchannelLogout(true)
.setAttribute(OIDCConfigAttributes.FRONT_CHANNEL_LOGOUT_URI, OAuthClient.APP_ROOT + "/admin/frontchannelLogout")
.update()) {
oauth.clientSessionState("client-session");
oauth.doLogin("test-user@localhost", "password");
String code = oauth.parseLoginResponse().getCode();
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);

View file

@ -110,7 +110,6 @@ public class LogoutCorsTest extends AbstractKeycloakTest {
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
return oauth.doAccessTokenRequest(code);
}

View file

@ -17,21 +17,26 @@
package org.keycloak.testsuite.oauth;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.Response.Status;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.hamcrest.MatcherAssert;
import org.jboss.arquillian.graphene.page.Page;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.keycloak.admin.client.resource.ClientResource;
import org.keycloak.admin.client.resource.ClientsResource;
import org.keycloak.common.util.Retry;
import org.keycloak.common.util.Time;
import org.keycloak.constants.AdapterConstants;
import org.keycloak.events.Details;
import org.keycloak.jose.jws.JWSHeader;
import org.keycloak.jose.jws.JWSInput;
import org.keycloak.models.Constants;
import org.keycloak.protocol.ProtocolMapper;
import org.keycloak.protocol.oidc.OIDCConfigAttributes;
import org.keycloak.protocol.oidc.OIDCLoginProtocol;
import org.keycloak.representations.AccessToken;
@ -45,29 +50,24 @@ import org.keycloak.testsuite.Assert;
import org.keycloak.testsuite.AssertEvents;
import org.keycloak.testsuite.admin.ApiUtil;
import org.keycloak.testsuite.pages.LoginPage;
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
import org.keycloak.testsuite.util.ClientManager;
import org.keycloak.testsuite.util.Matchers;
import org.keycloak.testsuite.util.ProtocolMapperUtil;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.TokenSignatureUtil;
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
import org.keycloak.testsuite.util.oauth.LogoutResponse;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import jakarta.ws.rs.core.HttpHeaders;
import jakarta.ws.rs.core.Response.Status;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
import org.keycloak.testsuite.util.ClientManager;
import org.keycloak.testsuite.util.Matchers;
import org.keycloak.testsuite.util.ProtocolMapperUtil;
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
import org.keycloak.testsuite.util.RealmBuilder;
import org.keycloak.testsuite.util.TokenSignatureUtil;
import org.keycloak.testsuite.util.oauth.LogoutResponse;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.keycloak.testsuite.admin.AbstractAdminTest.loadJson;
/**
@ -108,8 +108,7 @@ public class LogoutTest extends AbstractKeycloakTest {
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
AccessTokenResponse tokenResponse = oauth.accessTokenRequest(code).param(AdapterConstants.CLIENT_SESSION_STATE, "client-session").send();
String refreshTokenString = tokenResponse.getRefreshToken();
LogoutResponse response = oauth.doLogout(refreshTokenString);
@ -124,8 +123,7 @@ public class LogoutTest extends AbstractKeycloakTest {
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
AccessTokenResponse tokenResponse = oauth.accessTokenRequest(code).param(AdapterConstants.CLIENT_SESSION_STATE, "client-session").send();
String refreshTokenString = tokenResponse.getRefreshToken();
adminClient.realm("test").update(RealmBuilder.create().notBefore(Time.currentTime() + 1).build());
@ -168,8 +166,7 @@ public class LogoutTest extends AbstractKeycloakTest {
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
AccessTokenResponse tokenResponse = oauth.accessTokenRequest(code).param(AdapterConstants.CLIENT_SESSION_STATE, "client-session").send();
String refreshTokenString = tokenResponse.getRefreshToken();
oauth.client("test-app-scope", "password");
@ -206,8 +203,7 @@ public class LogoutTest extends AbstractKeycloakTest {
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
AccessTokenResponse tokenResponse = oauth.accessTokenRequest(code).param(AdapterConstants.CLIENT_SESSION_STATE, "client-session").send();
String idTokenString = tokenResponse.getIdToken();
JWSHeader header = new JWSInput(tokenResponse.getAccessToken()).getHeader();
@ -226,12 +222,12 @@ public class LogoutTest extends AbstractKeycloakTest {
assertNull(header.getContentType());
String logoutUrl = oauth.logoutForm()
.idTokenHint(idTokenString)
.postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
.build();
.idTokenHint(idTokenString)
.postLogoutRedirectUri(oauth.APP_AUTH_ROOT)
.build();
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
MatcherAssert.assertThat(response, Matchers.statusCodeIsHC(Status.FOUND));
MatcherAssert.assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT));
}
@ -263,9 +259,7 @@ public class LogoutTest extends AbstractKeycloakTest {
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
AccessTokenResponse tokenResponse = oauth.accessTokenRequest(code).param(AdapterConstants.CLIENT_SESSION_STATE, "client-session").send();
events.poll();
String idTokenString = tokenResponse.getIdToken();
String logoutUrl = oauth.logoutForm()
@ -274,7 +268,7 @@ public class LogoutTest extends AbstractKeycloakTest {
.build();
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
MatcherAssert.assertThat(response, Matchers.statusCodeIsHC(Status.FOUND));
MatcherAssert.assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT));
}
@ -303,9 +297,7 @@ public class LogoutTest extends AbstractKeycloakTest {
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
AccessTokenResponse tokenResponse = oauth.accessTokenRequest(code).param(AdapterConstants.CLIENT_SESSION_STATE, "client-session").send();
String idTokenString = tokenResponse.getIdToken();
String logoutUrl = oauth.logoutForm()
.idTokenHint(idTokenString)
@ -313,7 +305,7 @@ public class LogoutTest extends AbstractKeycloakTest {
.build();
try (CloseableHttpClient c = HttpClientBuilder.create().disableRedirectHandling().build();
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
CloseableHttpResponse response = c.execute(new HttpGet(logoutUrl))) {
MatcherAssert.assertThat(response, Matchers.statusCodeIsHC(Status.FOUND));
MatcherAssert.assertThat(response.getFirstHeader(HttpHeaders.LOCATION).getValue(), is(oauth.APP_AUTH_ROOT));
}
@ -348,9 +340,7 @@ public class LogoutTest extends AbstractKeycloakTest {
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
AccessTokenResponse tokenResponse = oauth.accessTokenRequest(code).param(AdapterConstants.CLIENT_SESSION_STATE, "client-session").send();
AccessToken accessToken = new JWSInput(tokenResponse.getAccessToken()).readJsonContent(AccessToken.class);
String idTokenString = tokenResponse.getIdToken();
String logoutUrl = oauth.logoutForm()
@ -399,9 +389,8 @@ public class LogoutTest extends AbstractKeycloakTest {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
AccessTokenResponse tokenResponse = oauth.accessTokenRequest(code).param(AdapterConstants.CLIENT_SESSION_STATE, "client-session").send();
setTimeOffset(1);

View file

@ -61,24 +61,14 @@ public class OAuthDanceClientSessionExtensionTest extends AbstractKeycloakTest {
String code = oauth.parseLoginResponse().getCode();
String clientSessionState = "1234";
String clientSessionHost = "test-client-host";
AccessTokenResponse tokenResponse = oauth.clientSessionState(clientSessionState)
.clientSessionHost(clientSessionHost)
.doAccessTokenRequest(code);
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
String refreshTokenString = tokenResponse.getRefreshToken();
EventRepresentation tokenEvent = events.expectCodeToToken(codeId, sessionId)
.assertEvent();
String updatedClientSessionState = "5678";
oauth.clientSessionState(updatedClientSessionState)
.clientSessionHost(clientSessionHost)
.doRefreshTokenRequest(refreshTokenString);
oauth.doRefreshTokenRequest(refreshTokenString);
events.expectRefresh(tokenEvent.getDetails().get(Details.REFRESH_TOKEN_ID), sessionId)
.assertEvent();

View file

@ -1070,7 +1070,6 @@ public class RPInitiatedLogoutTest extends AbstractTestRealmKeycloakTest {
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
events.clear();
return tokenResponse;

View file

@ -525,7 +525,6 @@ public class TokenIntrospectionTest extends AbstractTestRealmKeycloakTest {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);

View file

@ -131,7 +131,6 @@ public class TokenRevocationTest extends AbstractKeycloakTest {
@Test
public void testRevokeToken() throws Exception {
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse1 = login("test-app", "test-user@localhost", "password");
AccessTokenResponse tokenResponse2 = login("test-app-scope", "test-user@localhost", "password");

View file

@ -595,7 +595,6 @@ public class HoKTest extends AbstractTestRealmKeycloakTest {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);
verifyHoKTokenDefaultCertThumbPrint(tokenResponse);

View file

@ -490,7 +490,6 @@ public class StandardTokenExchangeV1Test extends AbstractKeycloakTest {
});
clients.get(rep.getId()).update(rep);
String logoutToken;
oauth.clientSessionState("client-session");
oauth.doLogin("user", "password");
String code = oauth.parseLoginResponse().getCode();
AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);

View file

@ -1031,7 +1031,6 @@ public class UserInfoTest extends AbstractKeycloakTest {
oauth.doLogin("test-user@localhost", "password");
String code = oauth.parseLoginResponse().getCode();
oauth.clientSessionState("client-session");
org.keycloak.testsuite.util.oauth.AccessTokenResponse tokenResponse = oauth.doAccessTokenRequest(code);