mirror of
https://github.com/keycloak/keycloak.git
synced 2025-12-16 20:15:46 -06:00
Avoid using UserCredentialManager from user storage extensions (#43695)
closes #43694 Signed-off-by: mposolda <mposolda@gmail.com>
This commit is contained in:
@@ -56,6 +56,25 @@ This prevents problems with client IDs or passwords that contain, for example, a
|
||||
|
||||
To revert to the old behavior, change the client authentication to *Client secret sent as HTTP Basic authentication without URL encoding (deprecated)* (`client_secret_basic_unencoded`).
|
||||
|
||||
=== Not recommended to use org.keycloak.credential.UserCredentialManager directly in your extensions
|
||||
|
||||
If you have user storage extension and you reference the class `org.keycloak.credential.UserCredentialManager` from your providers, it is recommended to avoid using this class directly as it might be
|
||||
moved to the private modules in the future releases. The class may be typically used in the method `credentialManager()` of the implementations of `UserModel` interface. In that case,
|
||||
it is recommended to replace the code like this:
|
||||
```
|
||||
@Override
|
||||
public SubjectCredentialManager credentialManager() {
|
||||
return new UserCredentialManager(keycloakSession, realmModel, this);
|
||||
}
|
||||
```
|
||||
with the code similar to this:
|
||||
```
|
||||
@Override
|
||||
public org.keycloak.models.UserCredentialManager credentialManager() {
|
||||
return keycloakSession.users().getUserCredentialManager(this);
|
||||
}
|
||||
```
|
||||
|
||||
=== Allowing realm administrators granted with the `realm-admin` role to assign admin roles
|
||||
|
||||
In previous versions, realm administrators granted with the `realm-admin` role were not able to grant admin roles for delegated realm administrators.
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.keycloak.credential.CredentialInput;
|
||||
import org.keycloak.models.ClientScopeModel;
|
||||
import org.keycloak.models.CredentialValidationOutput;
|
||||
import org.keycloak.models.IdentityProviderModel;
|
||||
import org.keycloak.models.UserCredentialManager;
|
||||
import org.keycloak.models.cache.infinispan.events.CacheKeyInvalidatedEvent;
|
||||
import org.keycloak.models.cache.infinispan.events.InvalidationEvent;
|
||||
import org.keycloak.common.constants.ServiceAccountConstants;
|
||||
@@ -1038,6 +1039,11 @@ public class UserCacheSession implements UserCache, OnCreateComponent, OnUpdateC
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserCredentialManager getUserCredentialManager(UserModel user) {
|
||||
return new org.keycloak.credential.UserCredentialManager(session, session.getContext().getRealm(), user);
|
||||
}
|
||||
|
||||
public UserCacheManager getCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RequiredActionProviderModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.UserCredentialManager;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserProvider;
|
||||
import org.keycloak.models.jpa.entities.CredentialEntity;
|
||||
@@ -961,6 +962,11 @@ public class JpaUserProvider implements UserProvider, UserCredentialStore, JpaUs
|
||||
return credentialStore.moveCredentialTo(realm, user, id, newPreviousCredentialId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserCredentialManager getUserCredentialManager(UserModel user) {
|
||||
return new org.keycloak.credential.UserCredentialManager(session, session.getContext().getRealm(), user);
|
||||
}
|
||||
|
||||
// Could override this to provide a custom behavior.
|
||||
protected void ensureEmailConstraint(List<UserEntity> users, RealmModel realm) {
|
||||
UserEntity user = users.get(0);
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.keycloak.common.Profile.Feature;
|
||||
import org.keycloak.common.util.CollectionUtil;
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.common.util.ObjectUtil;
|
||||
import org.keycloak.credential.UserCredentialManager;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.GroupModel.GroupMemberJoinEvent;
|
||||
@@ -577,7 +576,7 @@ public class UserAdapter implements UserModel, JpaModel<UserEntity> {
|
||||
|
||||
@Override
|
||||
public SubjectCredentialManager credentialManager() {
|
||||
return new UserCredentialManager(session, realm, this);
|
||||
return session.users().getUserCredentialManager(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -59,6 +59,7 @@ import org.keycloak.models.ProtocolMapperModel;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.RoleModel;
|
||||
import org.keycloak.models.UserConsentModel;
|
||||
import org.keycloak.models.UserCredentialManager;
|
||||
import org.keycloak.models.UserManager;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.models.UserProvider;
|
||||
@@ -1078,6 +1079,11 @@ public class UserStorageManager extends AbstractStorageManager<UserStorageProvid
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserCredentialManager getUserCredentialManager(UserModel user) {
|
||||
return new org.keycloak.credential.UserCredentialManager(session, session.getContext().getRealm(), user);
|
||||
}
|
||||
|
||||
private boolean isReadOnlyOrganizationMember(UserModel delegate) {
|
||||
if (delegate == null) {
|
||||
return false;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
package org.keycloak.storage.adapter;
|
||||
|
||||
import org.keycloak.credential.UserCredentialManager;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.SubjectCredentialManager;
|
||||
@@ -33,6 +32,6 @@ public class InMemoryUserAdapter extends AbstractInMemoryUserAdapter {
|
||||
|
||||
@Override
|
||||
public SubjectCredentialManager credentialManager() {
|
||||
return new UserCredentialManager(session, realm, this);
|
||||
return session.users().getUserCredentialManager(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import io.opentelemetry.api.trace.StatusCode;
|
||||
import org.keycloak.common.util.reflections.Types;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
import org.keycloak.models.SubjectCredentialManager;
|
||||
import org.keycloak.models.UserModel;
|
||||
import org.keycloak.storage.AbstractStorageManager;
|
||||
import org.keycloak.storage.DatastoreProvider;
|
||||
@@ -42,12 +41,15 @@ import java.util.stream.Stream;
|
||||
*
|
||||
* @author Alexander Schwartz
|
||||
*/
|
||||
public class UserCredentialManager extends AbstractStorageManager<UserStorageProvider, UserStorageProviderModel> implements SubjectCredentialManager {
|
||||
public class UserCredentialManager extends AbstractStorageManager<UserStorageProvider, UserStorageProviderModel> implements org.keycloak.models.UserCredentialManager {
|
||||
|
||||
private final UserModel user;
|
||||
private final KeycloakSession session;
|
||||
private final RealmModel realm;
|
||||
|
||||
/**
|
||||
* It is not recommended to use this method directly from your user-storage providers! Please use {@link org.keycloak.models.UserProvider#getUserCredentialManager(UserModel) session.users().getUserCredentialManager(user)} instead.
|
||||
*/
|
||||
public UserCredentialManager(KeycloakSession session, RealmModel realm, UserModel user) {
|
||||
super(session, UserStorageProviderFactory.class, UserStorageProvider.class, UserStorageProviderModel::new, "user");
|
||||
this.user = user;
|
||||
|
||||
@@ -18,7 +18,6 @@ package org.keycloak.storage.adapter;
|
||||
|
||||
import org.keycloak.common.util.MultivaluedHashMap;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.credential.UserCredentialManager;
|
||||
import org.keycloak.models.ClientModel;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
@@ -401,7 +400,7 @@ public abstract class AbstractUserAdapterFederatedStorage extends UserModelDefau
|
||||
|
||||
@Override
|
||||
public SubjectCredentialManager credentialManager() {
|
||||
return new UserCredentialManager(session, realm, this);
|
||||
return session.users().getUserCredentialManager(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -26,6 +26,9 @@ import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* Validates and manages the credentials of a known entity (for example, a user).
|
||||
*
|
||||
* NOTE: This class might be renamed to {@link org.keycloak.models.UserCredentialManager} in Keycloak 27. Please use the {@link org.keycloak.models.UserCredentialManager}
|
||||
* already if you can
|
||||
*/
|
||||
public interface SubjectCredentialManager {
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
package org.keycloak.models;
|
||||
|
||||
public interface UserCredentialManager extends SubjectCredentialManager {
|
||||
}
|
||||
@@ -297,4 +297,11 @@ public interface UserProvider extends Provider,
|
||||
*/
|
||||
void preRemove(RealmModel realm, ComponentModel component);
|
||||
|
||||
/**
|
||||
* Default implementation of {@link SubjectCredentialManager} suitable for most of user providers
|
||||
*
|
||||
* @return user credential manager
|
||||
*/
|
||||
UserCredentialManager getUserCredentialManager(UserModel user);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package org.keycloak.testsuite.federation;
|
||||
import org.keycloak.component.ComponentModel;
|
||||
import org.keycloak.credential.CredentialInput;
|
||||
import org.keycloak.credential.CredentialInputValidator;
|
||||
import org.keycloak.credential.UserCredentialManager;
|
||||
import org.keycloak.models.GroupModel;
|
||||
import org.keycloak.models.KeycloakSession;
|
||||
import org.keycloak.models.RealmModel;
|
||||
@@ -155,7 +154,7 @@ public class UserPropertyFileStorage implements UserLookupProvider, UserStorageP
|
||||
|
||||
@Override
|
||||
public SubjectCredentialManager credentialManager() {
|
||||
return new UserCredentialManager(session, realm, this);
|
||||
return session.users().getUserCredentialManager(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user