mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Set client in the session context for logout token encode
Closes #40984 Signed-off-by: rmartinc <rmartinc@redhat.com> Co-authored-by: rmartinc <rmartinc@redhat.com>
This commit is contained in:
parent
16255afa18
commit
cc2f76738a
@ -193,12 +193,17 @@ public class ResourceAdminManager {
|
||||
AuthenticatedClientSessionModel clientSessionModel, String managementUrl) {
|
||||
UserModel user = clientSessionModel.getUserSession().getUser();
|
||||
|
||||
LogoutToken logoutToken = session.tokens().initLogoutToken(resource, user, clientSessionModel);
|
||||
String token = session.tokens().encode(logoutToken);
|
||||
if (logger.isDebugEnabled())
|
||||
logger.debugv("logout resource {0} url: {1} sessionIds: ", resource.getClientId(), managementUrl);
|
||||
HttpPost post = null;
|
||||
ClientModel previousClient = session.getContext().getClient();
|
||||
try {
|
||||
session.getContext().setClient(resource);
|
||||
|
||||
LogoutToken logoutToken = session.tokens().initLogoutToken(resource, user, clientSessionModel);
|
||||
String token = session.tokens().encode(logoutToken);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debugv("logout resource {0} url: {1} sessionIds: ", resource.getClientId(), managementUrl);
|
||||
}
|
||||
|
||||
post = new HttpPost(managementUrl);
|
||||
List<NameValuePair> parameters = new LinkedList<>();
|
||||
if (logoutToken != null) {
|
||||
@ -223,6 +228,7 @@ public class ResourceAdminManager {
|
||||
ServicesLogger.LOGGER.logoutFailed(e, resource.getClientId());
|
||||
return Response.serverError().build();
|
||||
} finally {
|
||||
session.getContext().setClient(previousClient);
|
||||
if (post != null) {
|
||||
post.reset();
|
||||
}
|
||||
|
||||
@ -34,6 +34,7 @@ import org.keycloak.admin.client.resource.RealmResource;
|
||||
import org.keycloak.common.util.Retry;
|
||||
import org.keycloak.common.util.Time;
|
||||
import org.keycloak.constants.AdapterConstants;
|
||||
import org.keycloak.crypto.Algorithm;
|
||||
import org.keycloak.events.Details;
|
||||
import org.keycloak.jose.jws.JWSHeader;
|
||||
import org.keycloak.jose.jws.JWSInput;
|
||||
@ -51,6 +52,7 @@ 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.ClientAttributeUpdater;
|
||||
import org.keycloak.testsuite.updaters.RealmAttributeUpdater;
|
||||
import org.keycloak.testsuite.util.ClientManager;
|
||||
import org.keycloak.testsuite.util.Matchers;
|
||||
@ -60,6 +62,7 @@ import org.keycloak.testsuite.util.TokenSignatureUtil;
|
||||
import org.keycloak.testsuite.util.UserBuilder;
|
||||
import org.keycloak.testsuite.util.oauth.AccessTokenResponse;
|
||||
import org.keycloak.testsuite.util.oauth.LogoutResponse;
|
||||
import org.keycloak.testsuite.util.oauth.OAuthClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
@ -181,6 +184,46 @@ public class LogoutTest extends AbstractKeycloakTest {
|
||||
oauth.client("test-app", "password");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logoutBackchannelTwoClientsSpecificConfigurationIsUsed() throws Exception {
|
||||
final String defaultSignatureAlgorithm = adminClient.realm(oauth.getRealm()).toRepresentation().getDefaultSignatureAlgorithm();
|
||||
final String differentAlg = Algorithm.RS256.equals(defaultSignatureAlgorithm) ? Algorithm.RS512 : Algorithm.RS256;
|
||||
try (ClientAttributeUpdater updater = ClientAttributeUpdater.forClient(adminClient, oauth.getRealm(), oauth.getClientId())
|
||||
.setAttribute(OIDCConfigAttributes.ID_TOKEN_SIGNED_RESPONSE_ALG, differentAlg)
|
||||
.setAttribute(OIDCConfigAttributes.BACKCHANNEL_LOGOUT_URL, OAuthClient.APP_ROOT + "/admin/backchannelLogout")
|
||||
.update()) {
|
||||
|
||||
// login with test-app
|
||||
oauth.doLogin("test-user@localhost", "password");
|
||||
AccessTokenResponse tokenResponse = oauth.accessTokenRequest(oauth.parseLoginResponse().getCode())
|
||||
.param(AdapterConstants.CLIENT_SESSION_STATE, "client-session").send();
|
||||
Assert.assertNull(tokenResponse.getError());
|
||||
|
||||
// login with test-app-scope
|
||||
oauth.client("test-app-scope", "password");
|
||||
oauth.openLoginForm();
|
||||
AccessTokenResponse tokenResponse2 = oauth.accessTokenRequest(oauth.parseLoginResponse().getCode())
|
||||
.param(AdapterConstants.CLIENT_SESSION_STATE, "client-session").send();
|
||||
Assert.assertNull(tokenResponse2.getError());
|
||||
AccessToken accessToken = new JWSInput(tokenResponse2.getAccessToken()).readJsonContent(AccessToken.class);
|
||||
|
||||
// logout from test-app-scope
|
||||
oauth.logoutForm().idTokenHint(tokenResponse2.getIdToken()).open();
|
||||
|
||||
// check test-app backchannel is received
|
||||
String rawLogoutToken = testingClient.testApp().getBackChannelRawLogoutToken();
|
||||
|
||||
// check the logout token is OK and using correct signature algorithm
|
||||
JWSInput jwsInput = new JWSInput(rawLogoutToken);
|
||||
assertEquals(differentAlg, jwsInput.getHeader().getRawAlgorithm());
|
||||
LogoutToken logoutToken = jwsInput.readJsonContent(LogoutToken.class);
|
||||
validateLogoutToken(logoutToken);
|
||||
JWSHeader logoutTokenHeader = jwsInput.getHeader();
|
||||
assertEquals("logout+jwt", logoutTokenHeader.getType());
|
||||
assertEquals(accessToken.getSubject(), logoutToken.getSubject());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoveAuthSessionWhenUserSessionFromIdTokenIsInvalid() throws IOException {
|
||||
RealmResource realm = adminClient.realm("test");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user