Merge pull request #2068 from stianst/KEYCLOAK-2185
KEYCLOAK-2185 Add support to disable realm and user cache, and added …
This commit is contained in:
commit
94fa1b2c89
19 changed files with 142 additions and 175 deletions
|
@ -34,7 +34,9 @@ public class RealmRepresentation {
|
||||||
protected Boolean resetPasswordAllowed;
|
protected Boolean resetPasswordAllowed;
|
||||||
protected Boolean editUsernameAllowed;
|
protected Boolean editUsernameAllowed;
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
protected Boolean userCacheEnabled;
|
protected Boolean userCacheEnabled;
|
||||||
|
@Deprecated
|
||||||
protected Boolean realmCacheEnabled;
|
protected Boolean realmCacheEnabled;
|
||||||
|
|
||||||
//--- brute force settings
|
//--- brute force settings
|
||||||
|
@ -367,22 +369,6 @@ public class RealmRepresentation {
|
||||||
this.rememberMe = rememberMe;
|
this.rememberMe = rememberMe;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean isRealmCacheEnabled() {
|
|
||||||
return realmCacheEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRealmCacheEnabled(Boolean realmCacheEnabled) {
|
|
||||||
this.realmCacheEnabled = realmCacheEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean isUserCacheEnabled() {
|
|
||||||
return userCacheEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUserCacheEnabled(Boolean userCacheEnabled) {
|
|
||||||
this.userCacheEnabled = userCacheEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Boolean isVerifyEmail() {
|
public Boolean isVerifyEmail() {
|
||||||
return verifyEmail;
|
return verifyEmail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,18 @@
|
||||||
"provider": "jpa"
|
"provider": "jpa"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"userCache": {
|
||||||
|
"infinispan" : {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"realmCache": {
|
||||||
|
"infinispan" : {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"userSessionPersister": {
|
"userSessionPersister": {
|
||||||
"provider": "jpa"
|
"provider": "jpa"
|
||||||
},
|
},
|
||||||
|
|
|
@ -215,6 +215,21 @@ public class MyEventListenerProviderFactory implements EventListenerProviderFact
|
||||||
"max": 100
|
"max": 100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}]]></programlisting>
|
||||||
|
</para>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<title>Disabling a provider</title>
|
||||||
|
<para>
|
||||||
|
You can disable a provider by setting the enabled field for the provider to false in <literal>keycloak-server.json</literal>.
|
||||||
|
For example to disable the Infinispan user cache provider add:
|
||||||
|
<programlisting><![CDATA[{
|
||||||
|
"userCache": {
|
||||||
|
"infinispan" : {
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
}
|
||||||
}]]></programlisting>
|
}]]></programlisting>
|
||||||
</para>
|
</para>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -66,10 +66,10 @@ i18n-enabled=Internationalization Enabled
|
||||||
supported-locales=Supported Locales
|
supported-locales=Supported Locales
|
||||||
supported-locales.placeholder=Type a locale and enter
|
supported-locales.placeholder=Type a locale and enter
|
||||||
default-locale=Default Locale
|
default-locale=Default Locale
|
||||||
realm-cache-enabled=Realm Cache Enabled
|
realm-cache-clear=Realm Cache
|
||||||
realm-cache-enabled.tooltip=Enable/disable cache for realms, clients and roles.
|
realm-cache-clear.tooltip=Clears all entries from the realm cache (this will clear entries for all realms)
|
||||||
user-cache-enabled=User Cache Enabled
|
user-cache-clear=User Cache
|
||||||
user-cache-enabled.tooltip=Enable/disable cache for users and user role mappings.
|
user-cache-clear.tooltip=Clears all entries from the user cache (this will clear entries for all realms)
|
||||||
revoke-refresh-token=Revoke Refresh Token
|
revoke-refresh-token=Revoke Refresh Token
|
||||||
revoke-refresh-token.tooltip=If enabled refresh tokens can only be used once. Otherwise refresh tokens are not revoked when used and can be used multiple times.
|
revoke-refresh-token.tooltip=If enabled refresh tokens can only be used once. Otherwise refresh tokens are not revoked when used and can be used multiple times.
|
||||||
sso-session-idle=SSO Session Idle
|
sso-session-idle=SSO Session Idle
|
||||||
|
|
|
@ -349,8 +349,20 @@ module.controller('RealmThemeCtrl', function($scope, Current, Realm, realm, serv
|
||||||
}, true);
|
}, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
module.controller('RealmCacheCtrl', function($scope, Current, Realm, realm, serverInfo, $http, $location, Dialog, Notifications) {
|
module.controller('RealmCacheCtrl', function($scope, realm, RealmClearUserCache, RealmClearRealmCache, Notifications) {
|
||||||
genericRealmUpdate($scope, Current, Realm, realm, serverInfo, $http, $location, Dialog, Notifications, "/realms/" + realm.realm + "/cache-settings");
|
|
||||||
|
$scope.clearUserCache = function() {
|
||||||
|
RealmClearUserCache.save({ realm: realm.realm}, function () {
|
||||||
|
Notifications.success("User cache cleared");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.clearRealmCache = function() {
|
||||||
|
RealmClearRealmCache.save({ realm: realm.realm}, function () {
|
||||||
|
Notifications.success("Realm cache cleared");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.controller('RealmPasswordPolicyCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications, PasswordPolicy) {
|
module.controller('RealmPasswordPolicyCtrl', function($scope, Realm, realm, $http, $location, Dialog, Notifications, PasswordPolicy) {
|
||||||
|
|
|
@ -595,6 +595,18 @@ module.factory('RealmPushRevocation', function($resource) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.factory('RealmClearUserCache', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/clear-user-cache', {
|
||||||
|
realm : '@realm'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.factory('RealmClearRealmCache', function($resource) {
|
||||||
|
return $resource(authUrl + '/admin/realms/:realm/clear-realm-cache', {
|
||||||
|
realm : '@realm'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
module.factory('RealmSessionStats', function($resource) {
|
module.factory('RealmSessionStats', function($resource) {
|
||||||
return $resource(authUrl + '/admin/realms/:realm/session-stats', {
|
return $resource(authUrl + '/admin/realms/:realm/session-stats', {
|
||||||
realm : '@realm'
|
realm : '@realm'
|
||||||
|
|
|
@ -3,25 +3,19 @@
|
||||||
|
|
||||||
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
|
<form class="form-horizontal" name="realmForm" novalidate kc-read-only="!access.manageRealm">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="realmCacheEnabled">{{:: 'realm-cache-enabled' | translate}}</label>
|
<label class="col-md-2 control-label">{{:: 'realm-cache-clear' | translate}}</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input ng-model="realm.realmCacheEnabled" name="realmCacheEnabled" id="realmCacheEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
|
<button type="submit" data-ng-click="clearRealmCache()" class="btn btn-default">{{:: 'clear' | translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
<kc-tooltip>{{:: 'realm-cache-enabled.tooltip' | translate}}</kc-tooltip>
|
|
||||||
|
<kc-tooltip>{{:: 'realm-cache-clear.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-md-2 control-label" for="userCacheEnabled">{{:: 'user-cache-enabled' | translate}}</label>
|
<label class="col-md-2 control-label">{{:: 'user-cache-clear' | translate}}</label>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<input ng-model="realm.userCacheEnabled" name="userCacheEnabled" id="userCacheEnabled" onoffswitch on-text="{{:: 'onText' | translate}}" off-text="{{:: 'offText' | translate}}"/>
|
<button type="submit" data-ng-click="clearUserCache()" class="btn btn-default">{{:: 'clear' | translate}}</button>
|
||||||
</div>
|
|
||||||
<kc-tooltip>{{:: 'user-cache-enabled.tooltip' | translate}}</kc-tooltip>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-group" data-ng-show="access.manageRealm">
|
|
||||||
<div class="col-md-10 col-md-offset-2">
|
|
||||||
<button kc-save data-ng-disabled="!changed">{{:: 'save' | translate}}</button>
|
|
||||||
<button kc-reset data-ng-disabled="!changed">{{:: 'cancel' | translate}}</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
<kc-tooltip>{{:: 'user-cache-clear.tooltip' | translate}}</kc-tooltip>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -38,22 +38,16 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||||
session.getTransaction().enlistAfterCompletion(getTransaction());
|
session.getTransaction().enlistAfterCompletion(getTransaction());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MigrationModel getMigrationModel() {
|
public MigrationModel getMigrationModel() {
|
||||||
return getDelegate().getMigrationModel();
|
return getDelegate().getMigrationModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return cache.isEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
cache.setEnabled(enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RealmProvider getDelegate() {
|
public RealmProvider getDelegate() {
|
||||||
if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
|
if (!transactionActive) throw new IllegalStateException("Cannot access delegate without a transaction");
|
||||||
|
@ -149,7 +143,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||||
@Override
|
@Override
|
||||||
public RealmModel createRealm(String name) {
|
public RealmModel createRealm(String name) {
|
||||||
RealmModel realm = getDelegate().createRealm(name);
|
RealmModel realm = getDelegate().createRealm(name);
|
||||||
if (!cache.isEnabled()) return realm;
|
|
||||||
registerRealmInvalidation(realm.getId());
|
registerRealmInvalidation(realm.getId());
|
||||||
return realm;
|
return realm;
|
||||||
}
|
}
|
||||||
|
@ -157,14 +150,12 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||||
@Override
|
@Override
|
||||||
public RealmModel createRealm(String id, String name) {
|
public RealmModel createRealm(String id, String name) {
|
||||||
RealmModel realm = getDelegate().createRealm(id, name);
|
RealmModel realm = getDelegate().createRealm(id, name);
|
||||||
if (!cache.isEnabled()) return realm;
|
|
||||||
registerRealmInvalidation(realm.getId());
|
registerRealmInvalidation(realm.getId());
|
||||||
return realm;
|
return realm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RealmModel getRealm(String id) {
|
public RealmModel getRealm(String id) {
|
||||||
if (!cache.isEnabled()) return getDelegate().getRealm(id);
|
|
||||||
CachedRealm cached = cache.getCachedRealm(id);
|
CachedRealm cached = cache.getCachedRealm(id);
|
||||||
if (cached == null) {
|
if (cached == null) {
|
||||||
RealmModel model = getDelegate().getRealm(id);
|
RealmModel model = getDelegate().getRealm(id);
|
||||||
|
@ -184,7 +175,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RealmModel getRealmByName(String name) {
|
public RealmModel getRealmByName(String name) {
|
||||||
if (!cache.isEnabled()) return getDelegate().getRealmByName(name);
|
|
||||||
CachedRealm cached = cache.getCachedRealmByName(name);
|
CachedRealm cached = cache.getCachedRealmByName(name);
|
||||||
if (cached == null) {
|
if (cached == null) {
|
||||||
RealmModel model = getDelegate().getRealmByName(name);
|
RealmModel model = getDelegate().getRealmByName(name);
|
||||||
|
@ -218,7 +208,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeRealm(String id) {
|
public boolean removeRealm(String id) {
|
||||||
if (!cache.isEnabled()) return getDelegate().removeRealm(id);
|
|
||||||
cache.invalidateCachedRealmById(id);
|
cache.invalidateCachedRealmById(id);
|
||||||
|
|
||||||
RealmModel realm = getDelegate().getRealm(id);
|
RealmModel realm = getDelegate().getRealm(id);
|
||||||
|
@ -247,7 +236,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RoleModel getRoleById(String id, RealmModel realm) {
|
public RoleModel getRoleById(String id, RealmModel realm) {
|
||||||
if (!cache.isEnabled()) return getDelegate().getRoleById(id, realm);
|
|
||||||
CachedRole cached = cache.getRole(id);
|
CachedRole cached = cache.getRole(id);
|
||||||
if (cached != null && !cached.getRealm().equals(realm.getId())) {
|
if (cached != null && !cached.getRealm().equals(realm.getId())) {
|
||||||
cached = null;
|
cached = null;
|
||||||
|
@ -276,7 +264,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GroupModel getGroupById(String id, RealmModel realm) {
|
public GroupModel getGroupById(String id, RealmModel realm) {
|
||||||
if (!cache.isEnabled()) return getDelegate().getGroupById(id, realm);
|
|
||||||
CachedGroup cached = cache.getGroup(id);
|
CachedGroup cached = cache.getGroup(id);
|
||||||
if (cached != null && !cached.getRealm().equals(realm.getId())) {
|
if (cached != null && !cached.getRealm().equals(realm.getId())) {
|
||||||
cached = null;
|
cached = null;
|
||||||
|
@ -301,7 +288,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClientModel getClientById(String id, RealmModel realm) {
|
public ClientModel getClientById(String id, RealmModel realm) {
|
||||||
if (!cache.isEnabled()) return getDelegate().getClientById(id, realm);
|
|
||||||
CachedClient cached = cache.getApplication(id);
|
CachedClient cached = cache.getApplication(id);
|
||||||
if (cached != null && !cached.getRealm().equals(realm.getId())) {
|
if (cached != null && !cached.getRealm().equals(realm.getId())) {
|
||||||
cached = null;
|
cached = null;
|
||||||
|
@ -324,7 +310,6 @@ public class DefaultCacheRealmProvider implements CacheRealmProvider {
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
|
public ClientTemplateModel getClientTemplateById(String id, RealmModel realm) {
|
||||||
if (!cache.isEnabled()) return getDelegate().getClientTemplateById(id, realm);
|
|
||||||
CachedClientTemplate cached = cache.getClientTemplate(id);
|
CachedClientTemplate cached = cache.getClientTemplate(id);
|
||||||
if (cached != null && !cached.getRealm().equals(realm.getId())) {
|
if (cached != null && !cached.getRealm().equals(realm.getId())) {
|
||||||
cached = null;
|
cached = null;
|
||||||
|
|
|
@ -22,8 +22,6 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
|
||||||
protected Set<String> realmInvalidations = new HashSet<>();
|
protected Set<String> realmInvalidations = new HashSet<>();
|
||||||
protected Map<String, UserModel> managedUsers = new HashMap<>();
|
protected Map<String, UserModel> managedUsers = new HashMap<>();
|
||||||
|
|
||||||
protected boolean clearAll;
|
|
||||||
|
|
||||||
public DefaultCacheUserProvider(UserCache cache, KeycloakSession session) {
|
public DefaultCacheUserProvider(UserCache cache, KeycloakSession session) {
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
this.session = session;
|
this.session = session;
|
||||||
|
@ -32,13 +30,8 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnabled() {
|
public void clear() {
|
||||||
return cache.isEnabled();
|
cache.clear();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
cache.setEnabled(enabled);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -73,9 +66,6 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
|
||||||
@Override
|
@Override
|
||||||
public void commit() {
|
public void commit() {
|
||||||
if (delegate == null) return;
|
if (delegate == null) return;
|
||||||
if (clearAll) {
|
|
||||||
cache.clear();
|
|
||||||
}
|
|
||||||
runInvalidations();
|
runInvalidations();
|
||||||
transactionActive = false;
|
transactionActive = false;
|
||||||
}
|
}
|
||||||
|
@ -110,7 +100,6 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public UserModel getUserById(String id, RealmModel realm) {
|
public UserModel getUserById(String id, RealmModel realm) {
|
||||||
if (!cache.isEnabled()) return getDelegate().getUserById(id, realm);
|
|
||||||
if (isRegisteredForInvalidation(realm, id)) {
|
if (isRegisteredForInvalidation(realm, id)) {
|
||||||
return getDelegate().getUserById(id, realm);
|
return getDelegate().getUserById(id, realm);
|
||||||
}
|
}
|
||||||
|
@ -136,7 +125,6 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
|
||||||
|
|
||||||
username = username.toLowerCase();
|
username = username.toLowerCase();
|
||||||
|
|
||||||
if (!cache.isEnabled()) return getDelegate().getUserByUsername(username, realm);
|
|
||||||
if (realmInvalidations.contains(realm.getId())) {
|
if (realmInvalidations.contains(realm.getId())) {
|
||||||
return getDelegate().getUserByUsername(username, realm);
|
return getDelegate().getUserByUsername(username, realm);
|
||||||
}
|
}
|
||||||
|
@ -164,7 +152,6 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
|
||||||
|
|
||||||
email = email.toLowerCase();
|
email = email.toLowerCase();
|
||||||
|
|
||||||
if (!cache.isEnabled()) return getDelegate().getUserByEmail(email, realm);
|
|
||||||
if (realmInvalidations.contains(realm.getId())) {
|
if (realmInvalidations.contains(realm.getId())) {
|
||||||
return getDelegate().getUserByEmail(email, realm);
|
return getDelegate().getUserByEmail(email, realm);
|
||||||
}
|
}
|
||||||
|
@ -276,7 +263,6 @@ public class DefaultCacheUserProvider implements CacheUserProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean removeUser(RealmModel realm, UserModel user) {
|
public boolean removeUser(RealmModel realm, UserModel user) {
|
||||||
if (!cache.isEnabled()) return getDelegate().removeUser(realm, user);
|
|
||||||
registerUserInvalidation(realm, user.getId());
|
registerUserInvalidation(realm, user.getId());
|
||||||
return getDelegate().removeUser(realm, user);
|
return getDelegate().removeUser(realm, user);
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,34 +20,23 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
protected final Cache<String, Object> cache;
|
protected final Cache<String, Object> cache;
|
||||||
protected final ConcurrentHashMap<String, String> realmLookup;
|
protected final ConcurrentHashMap<String, String> realmLookup;
|
||||||
protected volatile boolean enabled = true;
|
|
||||||
|
|
||||||
public InfinispanRealmCache(Cache<String, Object> cache, ConcurrentHashMap<String, String> realmLookup) {
|
public InfinispanRealmCache(Cache<String, Object> cache, ConcurrentHashMap<String, String> realmLookup) {
|
||||||
this.cache = cache;
|
this.cache = cache;
|
||||||
this.realmLookup = realmLookup;
|
this.realmLookup = realmLookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Cache<String, Object> getCache() {
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clear() {
|
public void clear() {
|
||||||
cache.clear();
|
cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
if (this.enabled && !enabled) {
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CachedRealm getCachedRealm(String id) {
|
public CachedRealm getCachedRealm(String id) {
|
||||||
if (!enabled) return null;
|
|
||||||
return get(id, CachedRealm.class);
|
return get(id, CachedRealm.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +55,6 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCachedRealm(CachedRealm realm) {
|
public void addCachedRealm(CachedRealm realm) {
|
||||||
if (!enabled) return;
|
|
||||||
logger.tracev("Adding realm {0}", realm.getId());
|
logger.tracev("Adding realm {0}", realm.getId());
|
||||||
cache.putForExternalRead(realm.getId(), realm);
|
cache.putForExternalRead(realm.getId(), realm);
|
||||||
realmLookup.put(realm.getName(), realm.getId());
|
realmLookup.put(realm.getName(), realm.getId());
|
||||||
|
@ -74,14 +62,12 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CachedRealm getCachedRealmByName(String name) {
|
public CachedRealm getCachedRealmByName(String name) {
|
||||||
if (!enabled) return null;
|
|
||||||
String id = realmLookup.get(name);
|
String id = realmLookup.get(name);
|
||||||
return id != null ? getCachedRealm(id) : null;
|
return id != null ? getCachedRealm(id) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CachedClient getApplication(String id) {
|
public CachedClient getApplication(String id) {
|
||||||
if (!enabled) return null;
|
|
||||||
return get(id, CachedClient.class);
|
return get(id, CachedClient.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +79,6 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCachedClient(CachedClient app) {
|
public void addCachedClient(CachedClient app) {
|
||||||
if (!enabled) return;
|
|
||||||
logger.tracev("Adding application {0}", app.getId());
|
logger.tracev("Adding application {0}", app.getId());
|
||||||
cache.putForExternalRead(app.getId(), app);
|
cache.putForExternalRead(app.getId(), app);
|
||||||
}
|
}
|
||||||
|
@ -112,7 +97,6 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CachedGroup getGroup(String id) {
|
public CachedGroup getGroup(String id) {
|
||||||
if (!enabled) return null;
|
|
||||||
return get(id, CachedGroup.class);
|
return get(id, CachedGroup.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +108,6 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCachedGroup(CachedGroup role) {
|
public void addCachedGroup(CachedGroup role) {
|
||||||
if (!enabled) return;
|
|
||||||
logger.tracev("Adding group {0}", role.getId());
|
logger.tracev("Adding group {0}", role.getId());
|
||||||
cache.putForExternalRead(role.getId(), role);
|
cache.putForExternalRead(role.getId(), role);
|
||||||
}
|
}
|
||||||
|
@ -144,7 +127,6 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CachedRole getRole(String id) {
|
public CachedRole getRole(String id) {
|
||||||
if (!enabled) return null;
|
|
||||||
return get(id, CachedRole.class);
|
return get(id, CachedRole.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,7 +150,6 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCachedRole(CachedRole role) {
|
public void addCachedRole(CachedRole role) {
|
||||||
if (!enabled) return;
|
|
||||||
logger.tracev("Adding role {0}", role.getId());
|
logger.tracev("Adding role {0}", role.getId());
|
||||||
cache.putForExternalRead(role.getId(), role);
|
cache.putForExternalRead(role.getId(), role);
|
||||||
}
|
}
|
||||||
|
@ -186,7 +167,6 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CachedClientTemplate getClientTemplate(String id) {
|
public CachedClientTemplate getClientTemplate(String id) {
|
||||||
if (!enabled) return null;
|
|
||||||
return get(id, CachedClientTemplate.class);
|
return get(id, CachedClientTemplate.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +178,6 @@ public class InfinispanRealmCache implements RealmCache {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addCachedClientTemplate(CachedClientTemplate app) {
|
public void addCachedClientTemplate(CachedClientTemplate app) {
|
||||||
if (!enabled) return;
|
|
||||||
logger.tracev("Adding client template {0}", app.getId());
|
logger.tracev("Adding client template {0}", app.getId());
|
||||||
cache.putForExternalRead(app.getId(), app);
|
cache.putForExternalRead(app.getId(), app);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,19 +28,6 @@ public class InfinispanUserCache implements UserCache {
|
||||||
this.emailLookup = emailLookup;
|
this.emailLookup = emailLookup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setEnabled(boolean enabled) {
|
|
||||||
if (this.enabled && !enabled) {
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
this.enabled = enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CachedUser getCachedUser(String realmId, String id) {
|
public CachedUser getCachedUser(String realmId, String id) {
|
||||||
if (realmId == null || id == null) return null;
|
if (realmId == null || id == null) return null;
|
||||||
|
@ -48,12 +35,6 @@ public class InfinispanUserCache implements UserCache {
|
||||||
return user != null && realmId.equals(user.getRealm()) ? user : null;
|
return user != null && realmId.equals(user.getRealm()) ? user : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateCachedUser(String realmId, CachedUser user) {
|
|
||||||
logger.tracev("Invalidating user {0}", user.getId());
|
|
||||||
cache.remove(user.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invalidateCachedUserById(String realmId, String id) {
|
public void invalidateCachedUserById(String realmId, String id) {
|
||||||
logger.tracev("Invalidating user {0}", id);
|
logger.tracev("Invalidating user {0}", id);
|
||||||
|
|
|
@ -7,11 +7,9 @@ import org.keycloak.models.RealmProvider;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public interface CacheRealmProvider extends RealmProvider {
|
public interface CacheRealmProvider extends RealmProvider {
|
||||||
|
void clear();
|
||||||
RealmProvider getDelegate();
|
RealmProvider getDelegate();
|
||||||
|
|
||||||
boolean isEnabled();
|
|
||||||
void setEnabled(boolean enabled);
|
|
||||||
|
|
||||||
void registerRealmInvalidation(String id);
|
void registerRealmInvalidation(String id);
|
||||||
|
|
||||||
void registerApplicationInvalidation(String id);
|
void registerApplicationInvalidation(String id);
|
||||||
|
|
|
@ -8,8 +8,7 @@ import org.keycloak.models.UserProvider;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public interface CacheUserProvider extends UserProvider {
|
public interface CacheUserProvider extends UserProvider {
|
||||||
|
void clear();
|
||||||
UserProvider getDelegate();
|
UserProvider getDelegate();
|
||||||
boolean isEnabled();
|
|
||||||
void setEnabled(boolean enabled);
|
|
||||||
void registerUserInvalidation(RealmModel realm, String id);
|
void registerUserInvalidation(RealmModel realm, String id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,10 +55,6 @@ public interface RealmCache {
|
||||||
|
|
||||||
void invalidateGroupById(String id);
|
void invalidateGroupById(String id);
|
||||||
|
|
||||||
boolean isEnabled();
|
|
||||||
|
|
||||||
void setEnabled(boolean enabled);
|
|
||||||
|
|
||||||
CachedClientTemplate getClientTemplate(String id);
|
CachedClientTemplate getClientTemplate(String id);
|
||||||
|
|
||||||
void invalidateClientTemplate(CachedClientTemplate app);
|
void invalidateClientTemplate(CachedClientTemplate app);
|
||||||
|
|
|
@ -7,12 +7,11 @@ import org.keycloak.models.cache.entities.CachedUser;
|
||||||
* @version $Revision: 1 $
|
* @version $Revision: 1 $
|
||||||
*/
|
*/
|
||||||
public interface UserCache {
|
public interface UserCache {
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
CachedUser getCachedUser(String realmId, String id);
|
CachedUser getCachedUser(String realmId, String id);
|
||||||
|
|
||||||
void invalidateCachedUser(String realmId, CachedUser user);
|
|
||||||
|
|
||||||
void addCachedUser(String realmId, CachedUser user);
|
void addCachedUser(String realmId, CachedUser user);
|
||||||
|
|
||||||
CachedUser getCachedUserByUsername(String realmId, String name);
|
CachedUser getCachedUserByUsername(String realmId, String name);
|
||||||
|
@ -23,7 +22,4 @@ public interface UserCache {
|
||||||
|
|
||||||
void invalidateRealmUsers(String realmId);
|
void invalidateRealmUsers(String realmId);
|
||||||
|
|
||||||
boolean isEnabled();
|
|
||||||
|
|
||||||
void setEnabled(boolean enabled);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,25 +1,12 @@
|
||||||
package org.keycloak.services;
|
package org.keycloak.services;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.keycloak.models.*;
|
||||||
import org.keycloak.models.KeycloakContext;
|
|
||||||
import org.keycloak.models.KeycloakSession;
|
|
||||||
import org.keycloak.models.KeycloakSessionFactory;
|
|
||||||
import org.keycloak.models.KeycloakTransactionManager;
|
|
||||||
import org.keycloak.models.RealmProvider;
|
|
||||||
import org.keycloak.models.UserFederationManager;
|
|
||||||
import org.keycloak.models.UserProvider;
|
|
||||||
import org.keycloak.models.UserSessionProvider;
|
|
||||||
import org.keycloak.models.cache.CacheRealmProvider;
|
import org.keycloak.models.cache.CacheRealmProvider;
|
||||||
import org.keycloak.models.cache.CacheUserProvider;
|
import org.keycloak.models.cache.CacheUserProvider;
|
||||||
import org.keycloak.provider.Provider;
|
import org.keycloak.provider.Provider;
|
||||||
import org.keycloak.provider.ProviderFactory;
|
import org.keycloak.provider.ProviderFactory;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
* @author <a href="mailto:sthorger@redhat.com">Stian Thorgersen</a>
|
||||||
|
@ -35,8 +22,6 @@ public class DefaultKeycloakSession implements KeycloakSession {
|
||||||
private UserSessionProvider sessionProvider;
|
private UserSessionProvider sessionProvider;
|
||||||
private UserFederationManager federationManager;
|
private UserFederationManager federationManager;
|
||||||
private KeycloakContext context;
|
private KeycloakContext context;
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(DefaultKeycloakSession.class);
|
|
||||||
|
|
||||||
public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) {
|
public DefaultKeycloakSession(DefaultKeycloakSessionFactory factory) {
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
|
@ -51,16 +36,18 @@ public class DefaultKeycloakSession implements KeycloakSession {
|
||||||
}
|
}
|
||||||
|
|
||||||
private RealmProvider getRealmProvider() {
|
private RealmProvider getRealmProvider() {
|
||||||
if (factory.getDefaultProvider(CacheRealmProvider.class) != null) {
|
CacheRealmProvider cache = getProvider(CacheRealmProvider.class);
|
||||||
return getProvider(CacheRealmProvider.class);
|
if (cache != null) {
|
||||||
|
return cache;
|
||||||
} else {
|
} else {
|
||||||
return getProvider(RealmProvider.class);
|
return getProvider(RealmProvider.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private UserProvider getUserProvider() {
|
private UserProvider getUserProvider() {
|
||||||
if (factory.getDefaultProvider(CacheUserProvider.class) != null) {
|
CacheUserProvider cache = getProvider(CacheUserProvider.class);
|
||||||
return getProvider(CacheUserProvider.class);
|
if (cache != null) {
|
||||||
|
return cache;
|
||||||
} else {
|
} else {
|
||||||
return getProvider(UserProvider.class);
|
return getProvider(UserProvider.class);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +74,6 @@ public class DefaultKeycloakSession implements KeycloakSession {
|
||||||
userModel = getUserProvider();
|
userModel = getUserProvider();
|
||||||
}
|
}
|
||||||
return userModel;
|
return userModel;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Provider> T getProvider(Class<T> clazz) {
|
public <T extends Provider> T getProvider(Class<T> clazz) {
|
||||||
|
|
|
@ -79,20 +79,24 @@ public class DefaultKeycloakSessionFactory implements KeycloakSessionFactory {
|
||||||
} else {
|
} else {
|
||||||
for (ProviderFactory factory : pm.load(spi)) {
|
for (ProviderFactory factory : pm.load(spi)) {
|
||||||
Config.Scope scope = Config.scope(spi.getName(), factory.getId());
|
Config.Scope scope = Config.scope(spi.getName(), factory.getId());
|
||||||
factory.init(scope);
|
if (scope.getBoolean("enabled", true)) {
|
||||||
|
factory.init(scope);
|
||||||
|
|
||||||
if (spi.isInternal() && !isInternal(factory)) {
|
if (spi.isInternal() && !isInternal(factory)) {
|
||||||
log.warnv("{0} ({1}) is implementing the internal SPI {2}. This SPI is internal and may change without notice", factory.getId(), factory.getClass().getName(), spi.getName());
|
log.warnv("{0} ({1}) is implementing the internal SPI {2}. This SPI is internal and may change without notice", factory.getId(), factory.getClass().getName(), spi.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
factories.put(factory.getId(), factory);
|
||||||
|
} else {
|
||||||
|
log.debugv("SPI {0} provider {1} disabled", spi.getName(), factory.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
factories.put(factory.getId(), factory);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (factories.size() == 1) {
|
if (factories.size() == 1) {
|
||||||
provider = factories.values().iterator().next().getId();
|
provider = factories.values().iterator().next().getId();
|
||||||
this.provider.put(spi.getProviderClass(), provider);
|
this.provider.put(spi.getProviderClass(), provider);
|
||||||
|
|
||||||
log.debugv("Loaded SPI {0} (provider = {1})", spi.getName(), provider);
|
log.debugv("Loaded SPI {0} (provider = {1})", spi.getName(), provider);
|
||||||
} else {
|
} else {
|
||||||
log.debugv("Loaded SPI {0} (providers = {1})", spi.getName(), factories.keySet());
|
log.debugv("Loaded SPI {0} (providers = {1})", spi.getName(), factories.keySet());
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,16 +191,7 @@ public class RealmAdminResource {
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public RealmRepresentation getRealm() {
|
public RealmRepresentation getRealm() {
|
||||||
if (auth.hasView()) {
|
if (auth.hasView()) {
|
||||||
RealmRepresentation rep = ModelToRepresentation.toRepresentation(realm, false);
|
return ModelToRepresentation.toRepresentation(realm, false);
|
||||||
if (session.realms() instanceof CacheRealmProvider) {
|
|
||||||
CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms();
|
|
||||||
rep.setRealmCacheEnabled(cacheRealmProvider.isEnabled());
|
|
||||||
}
|
|
||||||
if (session.userStorage() instanceof CacheUserProvider) {
|
|
||||||
CacheUserProvider cache = (CacheUserProvider)session.userStorage();
|
|
||||||
rep.setUserCacheEnabled(cache.isEnabled());
|
|
||||||
}
|
|
||||||
return rep;
|
|
||||||
} else {
|
} else {
|
||||||
auth.requireAny();
|
auth.requireAny();
|
||||||
|
|
||||||
|
@ -227,14 +218,6 @@ public class RealmAdminResource {
|
||||||
logger.debug("updating realm: " + realm.getName());
|
logger.debug("updating realm: " + realm.getName());
|
||||||
try {
|
try {
|
||||||
RepresentationToModel.updateRealm(rep, realm);
|
RepresentationToModel.updateRealm(rep, realm);
|
||||||
if (rep.isRealmCacheEnabled() != null && session.realms() instanceof CacheRealmProvider) {
|
|
||||||
CacheRealmProvider cacheRealmProvider = (CacheRealmProvider)session.realms();
|
|
||||||
cacheRealmProvider.setEnabled(rep.isRealmCacheEnabled());
|
|
||||||
}
|
|
||||||
if (rep.isUserCacheEnabled() != null && session.userStorage() instanceof CacheUserProvider) {
|
|
||||||
CacheUserProvider cache = (CacheUserProvider)session.userStorage();
|
|
||||||
cache.setEnabled(rep.isUserCacheEnabled());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Refresh periodic sync tasks for configured federationProviders
|
// Refresh periodic sync tasks for configured federationProviders
|
||||||
List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
|
List<UserFederationProviderModel> federationProviders = realm.getUserFederationProviders();
|
||||||
|
@ -724,4 +707,35 @@ public class RealmAdminResource {
|
||||||
PartialImportManager partialImport = new PartialImportManager(rep, session, realm, adminEvent);
|
PartialImportManager partialImport = new PartialImportManager(rep, session, realm, adminEvent);
|
||||||
return partialImport.saveResources();
|
return partialImport.saveResources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear realm cache
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Path("clear-realm-cache")
|
||||||
|
@POST
|
||||||
|
public void clearRealmCache() {
|
||||||
|
auth.requireManage();
|
||||||
|
adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
|
||||||
|
CacheRealmProvider cache = session.getProvider(CacheRealmProvider.class);
|
||||||
|
if (cache != null) {
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear user cache
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Path("clear-user-cache")
|
||||||
|
@POST
|
||||||
|
public void clearUserCache() {
|
||||||
|
auth.requireManage();
|
||||||
|
adminEvent.operation(OperationType.ACTION).resourcePath(uriInfo).success();
|
||||||
|
CacheUserProvider cache = session.getProvider(CacheUserProvider.class);
|
||||||
|
if (cache != null) {
|
||||||
|
cache.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,18 @@
|
||||||
"provider": "${keycloak.userSessionPersister.provider:jpa}"
|
"provider": "${keycloak.userSessionPersister.provider:jpa}"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"userCache": {
|
||||||
|
"infinispan" : {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"realmCache": {
|
||||||
|
"infinispan" : {
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"timer": {
|
"timer": {
|
||||||
"provider": "basic"
|
"provider": "basic"
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue