commit
dd6b05224d
11 changed files with 80 additions and 17 deletions
|
@ -66,19 +66,6 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
|
||||||
} else {
|
} else {
|
||||||
initEmbedded();
|
initEmbedded();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Backwards compatibility
|
|
||||||
if (cacheManager.getCacheConfiguration(InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME) == null) {
|
|
||||||
logger.debugf("No configuration provided for '%s' cache. Using '%s' configuration as template",
|
|
||||||
InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME, InfinispanConnectionProvider.SESSION_CACHE_NAME);
|
|
||||||
|
|
||||||
Configuration sessionCacheConfig = cacheManager.getCacheConfiguration(InfinispanConnectionProvider.SESSION_CACHE_NAME);
|
|
||||||
if (sessionCacheConfig != null) {
|
|
||||||
ConfigurationBuilder confBuilder = new ConfigurationBuilder().read(sessionCacheConfig);
|
|
||||||
Configuration offlineSessionConfig = confBuilder.build();
|
|
||||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME, offlineSessionConfig);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,6 +126,7 @@ public class DefaultInfinispanConnectionProviderFactory implements InfinispanCon
|
||||||
|
|
||||||
Configuration sessionCacheConfiguration = sessionConfigBuilder.build();
|
Configuration sessionCacheConfiguration = sessionConfigBuilder.build();
|
||||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.SESSION_CACHE_NAME, sessionCacheConfiguration);
|
cacheManager.defineConfiguration(InfinispanConnectionProvider.SESSION_CACHE_NAME, sessionCacheConfiguration);
|
||||||
|
cacheManager.defineConfiguration(InfinispanConnectionProvider.OFFLINE_SESSION_CACHE_NAME, sessionCacheConfiguration);
|
||||||
cacheManager.defineConfiguration(InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME, sessionCacheConfiguration);
|
cacheManager.defineConfiguration(InfinispanConnectionProvider.LOGIN_FAILURE_CACHE_NAME, sessionCacheConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
<invalidation-cache name="realms" mode="SYNC"/>
|
<invalidation-cache name="realms" mode="SYNC"/>
|
||||||
<invalidation-cache name="users" mode="SYNC"/>
|
<invalidation-cache name="users" mode="SYNC"/>
|
||||||
<distributed-cache name="sessions" mode="SYNC" owners="1"/>
|
<distributed-cache name="sessions" mode="SYNC" owners="1"/>
|
||||||
|
<distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
|
||||||
<distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
|
<distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
|
||||||
</cache-container>
|
</cache-container>
|
||||||
<xsl:apply-templates select="node()|@*"/>
|
<xsl:apply-templates select="node()|@*"/>
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
<local-cache name="realms"/>
|
<local-cache name="realms"/>
|
||||||
<local-cache name="users"/>
|
<local-cache name="users"/>
|
||||||
<local-cache name="sessions"/>
|
<local-cache name="sessions"/>
|
||||||
|
<local-cache name="offlineSessions"/>
|
||||||
<local-cache name="loginFailures"/>
|
<local-cache name="loginFailures"/>
|
||||||
</cache-container>
|
</cache-container>
|
||||||
<xsl:apply-templates select="node()|@*"/>
|
<xsl:apply-templates select="node()|@*"/>
|
||||||
|
|
|
@ -17,9 +17,8 @@ import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
import org.keycloak.models.KeycloakSessionFactory;
|
||||||
import org.keycloak.models.cache.CacheRealmProvider;
|
import org.keycloak.models.cache.CacheRealmProvider;
|
||||||
import org.keycloak.models.cache.CacheRealmProviderFactory;
|
import org.keycloak.models.cache.CacheRealmProviderFactory;
|
||||||
import org.keycloak.models.cache.RealmCache;
|
import org.keycloak.models.cache.entities.CachedClient;
|
||||||
import org.keycloak.models.cache.entities.CachedRealm;
|
import org.keycloak.models.cache.entities.CachedRealm;
|
||||||
import org.keycloak.models.cache.entities.CachedUser;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
@ -143,11 +142,23 @@ public class InfinispanCacheRealmProviderFactory implements CacheRealmProviderFa
|
||||||
|
|
||||||
realmLookup.remove(realm.getName());
|
realmLookup.remove(realm.getName());
|
||||||
|
|
||||||
|
for (String r : realm.getRealmRoles().values()) {
|
||||||
|
realmCache.evictCachedRoleById(r);
|
||||||
|
}
|
||||||
|
|
||||||
for (String c : realm.getClients().values()) {
|
for (String c : realm.getClients().values()) {
|
||||||
realmCache.evictCachedApplicationById(c);
|
realmCache.evictCachedApplicationById(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.tracev("Realm removed realm={0}", realm.getName());
|
log.tracev("Realm removed realm={0}", realm.getName());
|
||||||
|
} else if (object instanceof CachedClient) {
|
||||||
|
CachedClient client = (CachedClient) object;
|
||||||
|
|
||||||
|
for (String r : client.getRoles().values()) {
|
||||||
|
realmCache.evictCachedRoleById(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.tracev("Client removed client={0}", client.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -160,6 +160,12 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
cache.remove(id);
|
cache.remove(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void evictCachedRoleById(String id) {
|
||||||
|
logger.tracev("Evicting role {0}", id);
|
||||||
|
cache.evict(id);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCachedRole(CachedRole role) {
|
public void addCachedRole(CachedRole role) {
|
||||||
if (!enabled) return;
|
if (!enabled) return;
|
||||||
|
|
|
@ -37,6 +37,8 @@ public interface RealmCache {
|
||||||
|
|
||||||
void invalidateRole(CachedRole role);
|
void invalidateRole(CachedRole role);
|
||||||
|
|
||||||
|
void evictCachedRoleById(String id);
|
||||||
|
|
||||||
void addCachedRole(CachedRole role);
|
void addCachedRole(CachedRole role);
|
||||||
|
|
||||||
void invalidateCachedRoleById(String id);
|
void invalidateCachedRoleById(String id);
|
||||||
|
|
|
@ -264,8 +264,6 @@ public class RealmAdminResource {
|
||||||
|
|
||||||
if (!new RealmManager(session).removeRealm(realm)) {
|
if (!new RealmManager(session).removeRealm(realm)) {
|
||||||
throw new NotFoundException("Realm doesn't exist");
|
throw new NotFoundException("Realm doesn't exist");
|
||||||
} else {
|
|
||||||
clearAdminEvents();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@ package org.keycloak.testsuite.admin;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.keycloak.admin.client.Keycloak;
|
||||||
|
import org.keycloak.admin.client.resource.ServerInfoResource;
|
||||||
|
import org.keycloak.models.Constants;
|
||||||
import org.keycloak.models.KeycloakSession;
|
import org.keycloak.models.KeycloakSession;
|
||||||
import org.keycloak.models.RealmModel;
|
import org.keycloak.models.RealmModel;
|
||||||
import org.keycloak.representations.idm.ClientRepresentation;
|
import org.keycloak.representations.idm.ClientRepresentation;
|
||||||
|
@ -90,6 +93,14 @@ public class RealmTest extends AbstractClientTest {
|
||||||
assertNames(keycloak.realms().findAll(), "master", "test");
|
assertNames(keycloak.realms().findAll(), "master", "test");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void loginAfterRemoveRealm() {
|
||||||
|
realm.remove();
|
||||||
|
|
||||||
|
ServerInfoResource serverInfoResource = Keycloak.getInstance("http://localhost:8081/auth", "master", "admin", "admin", Constants.ADMIN_CLI_CLIENT_ID).serverInfo();
|
||||||
|
serverInfoResource.getInfo();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void updateRealm() {
|
public void updateRealm() {
|
||||||
// first change
|
// first change
|
||||||
|
|
|
@ -331,6 +331,48 @@ public class RefreshTokenTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void refreshTokenClientDisabled() throws Exception {
|
||||||
|
oauth.doLogin("test-user@localhost", "password");
|
||||||
|
|
||||||
|
Event loginEvent = events.expectLogin().assertEvent();
|
||||||
|
|
||||||
|
String sessionId = loginEvent.getSessionId();
|
||||||
|
String codeId = loginEvent.getDetails().get(Details.CODE_ID);
|
||||||
|
|
||||||
|
String code = oauth.getCurrentQuery().get(OAuth2Constants.CODE);
|
||||||
|
|
||||||
|
AccessTokenResponse response = oauth.doAccessTokenRequest(code, "password");
|
||||||
|
String refreshTokenString = response.getRefreshToken();
|
||||||
|
RefreshToken refreshToken = oauth.verifyRefreshToken(refreshTokenString);
|
||||||
|
|
||||||
|
events.expectCodeToToken(codeId, sessionId).assertEvent();
|
||||||
|
|
||||||
|
try {
|
||||||
|
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
||||||
|
@Override
|
||||||
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
|
appRealm.getClientByClientId(oauth.getClientId()).setEnabled(false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
response = oauth.doRefreshTokenRequest(refreshTokenString, "password");
|
||||||
|
|
||||||
|
assertEquals(400, response.getStatusCode());
|
||||||
|
assertEquals("invalid_client", response.getError());
|
||||||
|
|
||||||
|
events.expectRefresh(refreshToken.getId(), sessionId).user((String) null).session((String) null).clearDetails().error(Errors.CLIENT_DISABLED).assertEvent();
|
||||||
|
} finally {
|
||||||
|
keycloakRule.configure(new KeycloakRule.KeycloakSetup() {
|
||||||
|
@Override
|
||||||
|
public void config(RealmManager manager, RealmModel adminstrationRealm, RealmModel appRealm) {
|
||||||
|
appRealm.getClientByClientId(oauth.getClientId()).setEnabled(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void refreshTokenUserSessionExpired() {
|
public void refreshTokenUserSessionExpired() {
|
||||||
oauth.doLogin("test-user@localhost", "password");
|
oauth.doLogin("test-user@localhost", "password");
|
||||||
|
|
|
@ -60,6 +60,7 @@ public class KeycloakServerDeploymentProcessor implements DeploymentUnitProcesso
|
||||||
st.addDependency(cacheContainerService.append("realms"));
|
st.addDependency(cacheContainerService.append("realms"));
|
||||||
st.addDependency(cacheContainerService.append("users"));
|
st.addDependency(cacheContainerService.append("users"));
|
||||||
st.addDependency(cacheContainerService.append("sessions"));
|
st.addDependency(cacheContainerService.append("sessions"));
|
||||||
|
st.addDependency(cacheContainerService.append("offlineSessions"));
|
||||||
st.addDependency(cacheContainerService.append("loginFailures"));
|
st.addDependency(cacheContainerService.append("loginFailures"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<local-cache name="realms"/>
|
<local-cache name="realms"/>
|
||||||
<local-cache name="users"/>
|
<local-cache name="users"/>
|
||||||
<local-cache name="sessions"/>
|
<local-cache name="sessions"/>
|
||||||
|
<local-cache name="offlineSessions"/>
|
||||||
<local-cache name="loginFailures"/>
|
<local-cache name="loginFailures"/>
|
||||||
</cache-container>
|
</cache-container>
|
||||||
<cache-container name="server" default-cache="default" module="org.wildfly.clustering.server">
|
<cache-container name="server" default-cache="default" module="org.wildfly.clustering.server">
|
||||||
|
@ -59,6 +60,7 @@
|
||||||
<invalidation-cache name="realms" mode="SYNC"/>
|
<invalidation-cache name="realms" mode="SYNC"/>
|
||||||
<invalidation-cache name="users" mode="SYNC"/>
|
<invalidation-cache name="users" mode="SYNC"/>
|
||||||
<distributed-cache name="sessions" mode="SYNC" owners="1"/>
|
<distributed-cache name="sessions" mode="SYNC" owners="1"/>
|
||||||
|
<distributed-cache name="offlineSessions" mode="SYNC" owners="1"/>
|
||||||
<distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
|
<distributed-cache name="loginFailures" mode="SYNC" owners="1"/>
|
||||||
</cache-container>
|
</cache-container>
|
||||||
<cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
|
<cache-container name="server" aliases="singleton cluster" default-cache="default" module="org.wildfly.clustering.server">
|
||||||
|
|
Loading…
Reference in a new issue