使用KeyClope的java自定义用户联合
我是新来的keydeave,我正在尝试定制keydeave的用户联盟。我创建了一个项目,在这个项目中,用户的选择似乎一切都很好。keydeave用户联盟识别我的适配器。问题是什么时候想要获得用户列表。请帮忙。我先谢谢你
在同一台keyclok wildfly服务器上,我在单机版上创建了一个新连接。持久化单元为userDs的xml文件,我还创建了适配器、提供者和工厂提供者
用户。爪哇
@NamedQueries({
@NamedQuery(name="getUserByUsername", query="select u from User u where u.usuario = :username"),
@NamedQuery(name="getUserByEmail", query="select u from User u where u.email = :email"),
@NamedQuery(name="getUserCount", query="select count(u) from User u"),
@NamedQuery(name="getAllUsers", query="select u from User u"),
@NamedQuery(name="searchForUser", query="select u from User u where " +
"( lower(u.usuario) like :search or u.email like :search ) order by u.usuario")})
@Table(name="usuario")
@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {`
private static final long serialVersionUID = 1L;
@Id
private String id;
private String usuario;
private String nombre;
private String apellidos;
private String email;
private String password;
}
用户适配器。爪哇
public class UserAdapter extends AbstractUserAdapterFederatedStorage {
private static final Logger logger = Logger.getLogger(UserAdapter.class);
protected User entity;
protected String keycloakId;
public UserAdapter(KeycloakSession session, RealmModel realm, ComponentModel model, User entity) {
super(session, realm, model);
this.entity = entity;
keycloakId = StorageId.keycloakId(model, entity.getId());
}
public String getPassword() {
return entity.getPassword();
}
public void setPassword(String password) {
entity.setPassword(password);
}
@Override
public String getUsername() {
return entity.getUsuario();
}
@Override
public void setUsername(String username) {
entity.setUsuario(username);
}
@Override
public void setEmail(String email) {
entity.setEmail(email);
}
@Override
public String getEmail() {
return entity.getEmail();
}
@Override
public String getId() {
return keycloakId;
}
@Override
public String getFirstName() {
return entity.getNombre();
}
@Override
public void setFirstName(String firstName) {
entity.setNombre(firstName);
}
@Override
public String getLastName() {
return entity.getApellidos();
}
@Override
public void setLastName(String lastName) {
entity.setApellidos(lastName);
}
UserStorageProviderFactory。爪哇
public class UserStorageProviderFactory implements org.keycloak.storage.UserStorageProviderFactory<UserStorageProvider> {
private static final Logger logger = Logger.getLogger(UserStorageProviderFactory.class);
@Override
public UserStorageProvider create(KeycloakSession session, ComponentModel model) {
try {
InitialContext ctx = new InitialContext();
logger.info("URL: " + "java:global/keycloak-jpa/" + UserStorageProvider.class.getSimpleName());
UserStorageProvider provider = (UserStorageProvider)ctx.lookup("java:global/keycloak-jpa/" + UserStorageProvider.class.getSimpleName());
provider.setModel(model);
provider.setSession(session);
return provider;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public String getId() {
return "keycloak-jpa-provider";
}
@Override
public String getHelpText() {
return "JPA Example User Storage Provider";
}
@Override
public void close() {
logger.info("Closing factory");
}
UserStorageProvider。爪哇
@Stateful
@Local(UserStorageProvider.class)
public class UserStorageProvider implements org.keycloak.storage.UserStorageProvider,
UserLookupProvider,
UserQueryProvider,
CredentialInputValidator,
CredentialInputUpdater,
OnUserCache {`
@PersistenceContext(unitName = "userDS")
protected EntityManager em;
private static final Logger logger = Logger.getLogger(UserStorageProvider.class);
public static final String PASSWORD_CACHE_KEY = UserAdapter.class.getName() + ".password";
protected KeycloakSession session;
protected ComponentModel model;
@Remove
@Override
public void close() {
logger.info("ingresando close");
}
public void preRemove(RealmModel realm) {
logger.info("ingresando preRemove(RealmModel realm)");
}
public void preRemove(RealmModel realm, GroupModel group) {
logger.info("ingresando preRemove(RealmModel realm, GroupModel group)");
}
public void preRemove(RealmModel realm, RoleModel role) {
logger.info("ingresando preRemove(RealmModel realm, GroupModel group)");
}
public boolean updateCredential(RealmModel realmModel, UserModel userModel, CredentialInput credentialInput) {
logger.info("ingresando updateCredential(RealmModel realmModel, UserModel userModel, CredentialInput credentialInput)");
if (!supportsCredentialType(credentialInput.getType()) || !(credentialInput instanceof UserCredentialModel)) return false;
UserCredentialModel cred = (UserCredentialModel) credentialInput;
UserAdapter adapter = getUserAdapter(userModel);
adapter.setPassword(cred.getValue());
return true;
}
public void disableCredentialType(RealmModel realmModel, UserModel userModel, String s) {
logger.info("ingresando disableCredentialType(RealmModel realmModel, UserModel userModel, String s)");
}
public Set<String> getDisableableCredentialTypes(RealmModel realmModel, UserModel userModel) {
logger.info("ingresando getDisableableCredentialTypes(RealmModel realmModel, UserModel userModel)");
return Collections.emptySet();
}
public boolean supportsCredentialType(String credentialType) {
logger.info("ingresando supportsCredentialType(String credentialType)");
return CredentialModel.PASSWORD.equals(credentialType);
}
public boolean isConfiguredFor(RealmModel realmModel, UserModel userModel, String credentialType) {
logger.info("ingresando isConfiguredFor(RealmModel realmModel, UserModel userModel, String credentialType)");
return supportsCredentialType(credentialType);
}
public boolean isValid(RealmModel realmModel, UserModel userModel, CredentialInput credentialInput) {
logger.info("ingresando isValid(RealmModel realmModel, UserModel userModel, CredentialInput credentialInput)");
if (!supportsCredentialType(credentialInput.getType()) || !(credentialInput instanceof UserCredentialModel)) return false;
UserCredentialModel cred = (UserCredentialModel)credentialInput;
String password = getPassword(userModel);
return password != null && password.equals(cred.getValue());
}
public UserModel getUserById(String id, RealmModel realmModel) {
logger.info("ingresando getUserById: " + id);
String persistenceId = StorageId.externalId(id);
User entity = em.find(User.class, persistenceId);
if (entity == null) {
logger.info("could not find user by id: " + id);
return null;
}
return new UserAdapter(session, realmModel, model, entity);
}
public UserModel getUserByUsername(String userName, RealmModel realmModel) {
logger.info("getUserByUsername: " + userName);
TypedQuery<User> query = em.createNamedQuery("getUserByUsername", User.class);
query.setParameter("username", userName);
List<User> result = query.getResultList();
if (result.isEmpty()) {
logger.info("could not find username: " + userName);
return null;
}
return new UserAdapter(session, realmModel, model, result.get(0));
}
public UserModel getUserByEmail(String s, RealmModel realmModel) {
logger.info("ingresando getUserByEmail(String s, RealmModel realmModel)");
return getUserByUsername(s, realmModel);
}
@Override
public int getUsersCount(RealmModel realmModel) {
logger.info("ingresando getUsersCount(RealmModel realmModel)");
Object count = em.createNamedQuery("getUserCount")
.getSingleResult();
return ((Number)count).intValue();
}
@Override
public List<UserModel> getUsers(final RealmModel realmModel) {
logger.info("ingresando getUsers(final RealmModel realmModel)");
return getUsers(realmModel, -1, -1);
}
@Override
public List<UserModel> getUsers(RealmModel realmModel, int firstResult, int maxResults) {
TypedQuery<User> query = em.createNamedQuery("getAllUsers", User.class);
return getUserModels(realmModel, firstResult, maxResults, query);
}
@Override
public List<UserModel> searchForUser(String search, RealmModel realmModel) {
return searchForUser(search, realmModel, -1, -1);
}
@Override
public List<UserModel> searchForUser(String search, RealmModel realmModel, int firstResult, int maxResults) {
TypedQuery<User> query = em.createNamedQuery("searchForUser", User.class);
query.setParameter("search", "%" + search.toLowerCase() + "%");
return getUserModels(realmModel, firstResult, maxResults, query);
}
private List<UserModel> getUserModels(RealmModel realmModel, int firstResult, int maxResults, TypedQuery<User> query) {
if (firstResult != -1) {
query.setFirstResult(firstResult);
}
if (maxResults != -1) {
query.setMaxResults(maxResults);
}
List<User> results = query.getResultList();
List<UserModel> users = new LinkedList<>();
for (User entity : results) users.add(new UserAdapter(session, realmModel, model, entity));
return users;
}
@Override
public List<UserModel> searchForUser(Map<String, String> map, RealmModel realmModel) {
System.out.println("ingresando searchForUser(Map<String, String> map, RealmModel realmModel)");
return searchForUser("", realmModel);
}
@Override
public List<UserModel> searchForUser(Map<String, String> map, RealmModel realmModel, int i, int i1) {
System.out.println("ingresando searchForUser(Map<String, String> map, RealmModel realmModel, int i, int i1)");
return searchForUser("", realmModel);
}
@Override
public List<UserModel> getGroupMembers(RealmModel realmModel, GroupModel groupModel, int i, int i1) {
System.out.println("ingresando getGroupMembers(RealmModel realmModel, GroupModel groupModel, int i, int i1)");
return Collections.emptyList();
}
@Override
public List<UserModel> getGroupMembers(RealmModel realmModel, GroupModel groupModel) {
System.out.println("ingresando getGroupMembers(RealmModel realmModel, GroupModel groupModel)");
return Collections.emptyList();
}
@Override
public List<UserModel> searchForUserByUserAttribute(String s, String s1, RealmModel realmModel) {
System.out.println("ingresando searchForUserByUserAttribute(String s, String s1, RealmModel realmModel)");
return null;
}
@Override
public void onCache(RealmModel realmModel, CachedUserModel cachedUserModel, UserModel userModel) {
String password = ((UserAdapter)userModel).getPassword();
if (password != null) {
cachedUserModel.getCachedWith().put(PASSWORD_CACHE_KEY, password);
}
}
public String getPassword(UserModel user) {
String password = null;
if (user instanceof CachedUserModel) {
password = (String)((CachedUserModel)user).getCachedWith().get(PASSWORD_CACHE_KEY);
} else if (user instanceof UserAdapter) {
password = ((UserAdapter)user).getPassword();
}
return password;
}
public UserAdapter getUserAdapter(UserModel user) {
UserAdapter adapter = null;
if (user instanceof CachedUserModel) {
adapter = (UserAdapter)((CachedUserModel)user).getDelegateForUpdate();
} else {
adapter = (UserAdapter)user;
}
return adapter;
}
public void setModel(ComponentModel model) {
this.model = model;`enter code here`
}
public void setSession(KeycloakSession session) {
this.session = session;
}
我将jar部署到Keyclope wildfly服务器中,它可以在选项user federation中识别我的新适配器,但当我尝试列出用户时,我遇到以下错误:
17:56:40,460 ERROR [org.hibernate.engine.jdbc.spi.SqlExceptionHelper] (default task-2) javax.resource.ResourceException: IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@762c7243[state=DESTROYED managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@2b300f6c connection handles=0 lastReturned=1565819800458 lastValidated=1565819732106 lastCheckedOut=1565819800454 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@e92a386 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool@4743ffe9[pool=userDS] xaResource=LocalXAResourceImpl@3e8f3c8b[connectionListener=762c7243 connectionManager=2c5ddfb5 warned=false currentXid=null productName=PostgreSQL productVersion=10.9 (Ubuntu 10.9-0ubuntu0.18.04.1) jndiName=java:jboss/datasources/userDS] txSync=null] 17:56:40,470 ERROR [org.jboss.as.ejb3.invocation] (default task-2) WFLYEJB0034: EJB Invocation failed on component UserStorageProvider for method public java.util.List org.keycloak.provider.UserStorageProvider.searchForUser(java.util.Map,org.keycloak.models.RealmModel,int,int): javax.ejb.EJBTransactionRolledbackException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:203) org.keycloak.provider.UserStorageProvider$$$view1.searchForUser(Unknown Source) at org.keycloak.storage.UserStorageManager.lambda$searchForUser$2(UserStorageManager.java:556) at org.keycloak.storage.UserStorageManager.query(UserStorageManager.java:505) at org.keycloak.storage.UserStorageManager.searchForUser(UserStorageManager.java:554) at org.keycloak.models.cache.infinispan.UserCacheSession.searchForUser(UserCacheSession.java:583) at org.keycloak.services.resources.admin.UsersResource.searchForUser(UsersResource.java:247) at org.keycloak.services.resources.admin.UsersResource.getUsers(UsersResource.java:220) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) org.keycloak.services.filters.KeycloakSessionServletFilter.doFilter(KeycloakSessionServletFilter.java:90) org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1514) at org.hibernate.query.Query.getResultList(Query.java:132) at org.keycloak.provider.UserStorageProvider.getUserModels(UserStorageProvider.java:182) at org.keycloak.provider.UserStorageProvider.searchForUser(UserStorageProvider.java:172) at org.keycloak.provider.UserStorageProvider.searchForUser(UserStorageProvider.java:165) at org.keycloak.provider.UserStorageProvider.searchForUser(UserStorageProvider.java:197) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422) org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148) at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1984) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1914) at org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1892) at org.hibernate.loader.Loader.doQuery(Loader.java:937) at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:340) at org.hibernate.loader.Loader.doList(Loader.java:2689) at org.hibernate.loader.Loader.doList(Loader.java:2672) at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2506) at org.hibernate.loader.Loader.list(Loader.java:2501) at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:504) at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:395) at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:220) at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1507) at org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1537) at org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1505) ... 138 more Caused by: java.sql.SQLException: javax.resource.ResourceException: IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@762c7243[state=DESTROYED managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@2b300f6c connection handles=0 lastReturned=1565819800458 lastValidated=1565819732106 lastCheckedOut=1565819800454 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@e92a386 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool@4743ffe9[pool=userDS] xaResource=LocalXAResourceImpl@3e8f3c8b[connectionListener=762c7243 connectionManager=2c5ddfb5 warned=false currentXid=null productName=PostgreSQL productVersion=10.9 (Ubuntu 10.9-0ubuntu0.18.04.1) jndiName=java:jboss/datasources/userDS] txSync=null] at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:146) at org.jboss.as.connector.subsystems.datasources.WildFlyDataSource.getConnection(WildFlyDataSource.java:64) at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) at org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:35) at org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:106) ... 158 more Caused by: javax.resource.ResourceException: IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@762c7243[state=DESTROYED managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@2b300f6c connection handles=0 lastReturned=1565819800458 lastValidated=1565819732106 lastCheckedOut=1565819800454 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@e92a386 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool@4743ffe9[pool=userDS] xaResource=LocalXAResourceImpl@3e8f3c8b[connectionListener=762c7243 connectionManager=2c5ddfb5 warned=false currentXid=null productName=PostgreSQL productVersion=10.9 (Ubuntu 10.9-0ubuntu0.18.04.1) jndiName=java:jboss/datasources/userDS] txSync=null] at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.reconnectManagedConnection(AbstractConnectionManager.java:1055) at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:792) at org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:138) ... 162 more Caused by: javax.resource.ResourceException: IJ000461: Could not enlist in transaction on entering meta-aware object at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.managedConnectionReconnected(TxConnectionManagerImpl.java:571) at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.reconnectManagedConnection(AbstractConnectionManager.java:977) ... 164 more Caused by: javax.transaction.SystemException: Error enlisting resource in transaction=Local transaction (delegate=TransactionImple < ac, BasicAction: 0:ffff7f000101:-2c55aa43:5d54831c:2d7 status: ActionStatus.ABORT_ONLY >, owner=Local transaction context for provider JBoss JTA transaction provider) at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener$TransactionSynchronization.checkEnlisted(TxConnectionListener.java:956) at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist(TxConnectionListener.java:394) at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.managedConnectionReconnected(TxConnectionManagerImpl.java:564)
Caused by: java.lang.Throwable: Failed to enlist at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener$TransactionSynchronization.enlist(TxConnectionListener.java:1000) at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist(TxConnectionListener.java:379) ... 166 more
17:56:40,476 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-2) Uncaught server error: javax.ejb.EJBTransactionRolledbackException: org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:203) at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:364) at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:144) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422) at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422) org.keycloak.storage.UserStorageManager.query(UserStorageManager.java:505) at org.keycloak.storage.UserStorageManager.searchForUser(UserStorageManager.java:554) at org.keycloak.models.cache.infinispan.UserCacheSession.searchForUser(UserCacheSession.java:583) at org.keycloak.services.resources.admin.UsersResource.searchForUser(UsersResource.java:247) Caused by: javax.resource.ResourceException: IJ000457: Unchecked throwable in managedConnectionReconnected() cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@762c7243[state=DESTROYED managed connection=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@2b300f6c connection handles=0 lastReturned=1565819800458 lastValidated=1565819732106 lastCheckedOut=1565819800454 trackByTx=false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@e92a386 mcp=SemaphoreConcurrentLinkedQueueManagedConnectionPool@4743ffe9[pool=userDS] xaResource=LocalXAResourceImpl@3e8f3c8b[connectionListener=762c7243 connectionManager=2c5ddfb5 warned=false currentXid=null productName=PostgreSQL productVersion=10.9 (Ubuntu 10.9-0ubuntu0.18.04.1) jndiName=java:jboss/datasources/userDS] txSync=null] at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.reconnectManagedConnection(AbstractConnectionManager.java:1055) Caused by: java.lang.Throwable: Failed to enlist at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener$TransactionSynchronization.enlist(TxConnectionListener.java:1000) at org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist(TxConnectionListener.java:379)
17:56:40,480 ERROR [org.jboss.as.ejb3.invocation] (default task-2) WFLYEJB0034: EJB Invocation failed on component UserStorageProvider for method public void org.keycloak.provider.UserStorageProvider.close(): javax.ejb.NoSuchEJBException: WFLYEJB0168: Could not find EJB with id UUIDSessionID [4a1304ec-ca2f-4cbf-8de2-846bcc0d9892] at org.jboss.as.ejb3.component.stateful.StatefulComponentInstanceInterceptor.processInvocation(StatefulComponentInstanceInterceptor.java:55)
共 (0) 个答案