带有密钥斗篷的自定义用户联盟

时间:2019-08-14 23:21:20

标签: java keycloak

我是keycloak的新手,我试图自定义keycloak的用户联合会,我创建了一个项目,在开始时,一切似乎都很好,在用户的选择中,keycloak用户联合会认为我的适配器存在问题是要获取用户列表的时间。请一些帮助。我先谢谢你

在同一台keyclok wildfly服务器上,我在standalone.xml文件中创建了一个新连接,其中持久性单元是userD,我还创建了适配器,提供程序和工厂提供程序。

User.java

@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;
}

UserAdapter.java

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.java

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.java

@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部署到keycloak wildfly服务器中没有问题,它可以在选项用户联合中识别我的新适配器,但是当我尝试列出用户时,出现此错误:

  

17:56:40,460错误[org.hibernate.engine.jdbc.spi.SqlExceptionHelper](默认任务2)javax.resource.ResourceException:IJ000457:managedConnectionReconnected()cl = org.jboss.jca中未经检查的throwable。 core.connectionmanager.listener.TxConnectionListener@762c7243 [state = DESTROYED托管连接=org.jboss.jca.adapters.jdbc.local.LocalManagedConnection@2b300f6c连接句柄= 0 lastReturned = 1565819800458 lastValidated = 1565819732106 lastCheckedOut = 1565819800454 trackByTx = .jboss.jca.core.connectionmanager.pool.strategy.OnePool @ e92a386 mcp = SemaphoreConcurrentLinkedQueueManagedConnectionPool @ 4743ffe9 [pool = userDS] xaResource = LocalXAResourceImpl @ 3e8f3c8b [connectionListener = PostgreSQLc7243 connectionManager = 2c5ddfb5 warn = 9 (Ubuntu 10.9-0ubuntu0.18.04.1)jndiName = java:jboss / datasources / userDS] txSync = null]   17:56:40,470错误[org.jboss.as.ejb3.invocation](默认任务2)WFLYEJB0034:方法Public java.util.List org.keycloak.provider.UserStorageProvider.searchForUser(java)的组件UserStorageProvider上的EJB调用失败.util.Map,org.keycloak.models.RealmModel,int,int):javax.ejb.EJBTransactionRolledbackException:org.hibernate.exception.GenericJDBCException:无法获取JDBC连接       在org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:203)   org.keycloak.provider.UserStorageProvider $$$ view1.searchForUser(未知来源)       在org.keycloak.storage.UserStorageManager.lambda $ searchForUser $ 2(UserStorageManager.java:556)       在org.keycloak.storage.UserStorageManager.query(UserStorageManager.java:505)       在org.keycloak.storage.UserStorageManager.searchForUser(UserStorageManager.java:554)       在org.keycloak.models.cache.infinispan.UserCacheSession.searchForUser(UserCacheSession.java:583)       在org.keycloak.services.resources.admin.UsersResource.searchForUser(UsersResource.java:247)       在org.keycloak.services.resources.admin.UsersResource.getUsers(UsersResource.java:220)       在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处       在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)       在org.hibernate.query.Query.getResultList(Query.java:132)       在org.keycloak.provider.UserStorageProvider.getUserModels(UserStorageProvider.java:182)       在org.keycloak.provider.UserStorageProvider.searchForUser(UserStorageProvider.java:172)       在org.keycloak.provider.UserStorageProvider.searchForUser(UserStorageProvider.java:165)       在org.keycloak.provider.UserStorageProvider.searchForUser(UserStorageProvider.java:197)       在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处       在sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)       在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)       在java.lang.reflect.Method.invoke(Method.java:498)       在org.jboss.as.ee.component.ManagedReferenceMethodInterceptor.processInvocation(ManagedReferenceMethodInterceptor.java:52)处       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)   org.hibernate.engine.jdbc.internal.StatementPreparerImpl.prepareQueryStatement(StatementPreparerImpl.java:148)       在org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1984)       在org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1914)       在org.hibernate.loader.Loader.executeQueryStatement(Loader.java:1892)       在org.hibernate.loader.Loader.doQuery(Loader.java:937)       在org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:340)       在org.hibernate.loader.Loader.doList(Loader.java:2689)       在org.hibernate.loader.Loader.doList(Loader.java:2672)       在org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2506)       在org.hibernate.loader.Loader.list(Loader.java:2501)       在org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:504)       在org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:395)       在org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:220)       在org.hibernate.internal.SessionImpl.list(SessionImpl.java:1507)       在org.hibernate.query.internal.AbstractProducedQuery.doList(AbstractProducedQuery.java:1537)       在org.hibernate.query.internal.AbstractProducedQuery.list(AbstractProducedQuery.java:1505)       ...另外138个   造成原因:java.sql.SQLException:javax.resource.ResourceException:IJ000457:managedConnectionReconnected()中未选中的throwable cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@762c7243 [state = DESTROYED托管连接= org.jboss .jca.adapters.jdbc.local.LocalManagedConnection @ 2b300f6c连接句柄= 0 lastReturned = 1565819800458 lastValidated = 1565819732106 lastCheckedOut = 1565819800454 trackByTx = false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@S92edeemadConnectionConcurrenteConnectionConqueeConnection @ 4743ffe9 [pool = userDS] xaResource = LocalXAResourceImpl @ 3e8f3c8b [connectionListener = 762c7243 connectionManager = 2c5ddfb5warning = false currentXid = null productName = PostgreSQL productVersion = 10.9(Ubuntu 10.9-0ubuntu0.18.04.1)jndiName = java:jbosDS / data ] txSync = null]       在org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:146)       在org.jboss.as.connector.subsystems.datasources.WildFlyDataSource.getConnection(WildFlyDataSource.java:64)       在org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)       在org.hibernate.internal.NonContextualJdbcConnectionAccess.obtainConnection(NonContextualJdbcConnectionAccess.java:35)       在org.hibernate.resource.jdbc.internal.LogicalConnectionManagedImpl.acquireConnectionIfNeeded(LogicalConnectionManagedImpl.java:106)       ...更多158   引起原因:javax.resource.ResourceException:IJ000457:managedConnectionReconnected()中未经检查的可抛出对象cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@762c7243 [state = DESTROYED托管连接= org.jboss.jca.adapters.jdbc .local.LocalManagedConnection @ 2b300f6c连接句柄= 0 lastReturned = 1565819800458 lastValidated = 1565819732106 lastCheckedOut = 1565819800454 trackByTx = false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@e92a386 mcp = SemaphoreConcurrentLinkedQueue [474 = 474] ] 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       在org.jboss.jca.core.connectionmanager.AbstractConnectionManager.reconnectManagedConnection(AbstractConnectionManager.java:1055)       在org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:792)       在org.jboss.jca.adapters.jdbc.WrapperDataSource.getConnection(WrapperDataSource.java:138)       ...另外162个   由以下原因引起:javax.resource.ResourceException:IJ000461:输入元感知对象时无法加入事务       在org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.managedConnectionReconnected(TxConnectionManagerImpl.java:571)       在org.jboss.jca.core.connectionmanager.AbstractConnectionManager.reconnectManagedConnection(AbstractConnectionManager.java:977)       ...还有164个   由以下原因引起:javax.transaction.SystemException:错误在事务=本地事务中注册资源(代理= TransactionImple ,owner =提供者的本地事务上下文JBoss JTA交易提供者)       在org.jboss.jca.core.connectionmanager.listener.TxConnectionListener $ TransactionSynchronization.checkEnlisted(TxConnectionListener.java:956)       在org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist(TxConnectionListener.java:394)       在org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.managedConnectionReconnected(TxConnectionManagerImpl.java:564)

     

原因:java.lang.Throwable:无法入伍       在org.jboss.jca.core.connectionmanager.listener.TxConnectionListener $ TransactionSynchronization.enlist(TxConnectionListener.java:1000)处       在org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist(TxConnectionListener.java:379)       ...另外166

     

17:56:40,476错误[org.keycloak.services.error.KeycloakErrorHandler](默认任务2)未捕获的服务器错误:javax.ejb.EJBTransactionRolledbackException:org.hibernate.exception.GenericJDBCException:无法获取JDBC连接       在org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInCallerTx(CMTTxInterceptor.java:203)       在org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:364)       在org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:144)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)       在org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)       在org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:422)       org.keycloak.storage.UserStorageManager.query(UserStorageManager.java:505)       在org.keycloak.storage.UserStorageManager.searchForUser(UserStorageManager.java:554)       在org.keycloak.models.cache.infinispan.UserCacheSession.searchForUser(UserCacheSession.java:583)       在org.keycloak.services.resources.admin.UsersResource.searchForUser(UsersResource.java:247)   引起原因:javax.resource.ResourceException:IJ000457:managedConnectionReconnected()中未经检查的可抛出对象cl=org.jboss.jca.core.connectionmanager.listener.TxConnectionListener@762c7243 [state = DESTROYED托管连接= org.jboss.jca.adapters.jdbc .local.LocalManagedConnection @ 2b300f6c连接句柄= 0 lastReturned = 1565819800458 lastValidated = 1565819732106 lastCheckedOut = 1565819800454 trackByTx = false pool=org.jboss.jca.core.connectionmanager.pool.strategy.OnePool@e92a386 mcp = SemaphoreConcurrentLinkedQueue [474 = 474] ] 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       在org.jboss.jca.core.connectionmanager.AbstractConnectionManager.reconnectManagedConnection(AbstractConnectionManager.java:1055)   引起原因:java.lang.Throwable:报名失败       在org.jboss.jca.core.connectionmanager.listener.TxConnectionListener $ TransactionSynchronization.enlist(TxConnectionListener.java:1000)处       在org.jboss.jca.core.connectionmanager.listener.TxConnectionListener.enlist(TxConnectionListener.java:379)

     

17:56:40,480错误[org.jboss.as.ejb3.invocation](默认任务2)WFLYEJB0034:方法Public void org.keycloak.provider.UserStorageProvider.close()的组件UserStorageProvider上的EJB调用失败: javax.ejb.NoSuchEJBException:WFLYEJB0168:找不到ID为UUIDSessionID [4a1304ec-ca2f-4cbf-8de2-846bcc0d9892]的EJB。       在org.jboss.as.ejb3.component.stateful.StatefulComponentInstanceInterceptor.processInvocation(StatefulComponentInstanceInterceptor.java:55)上

0 个答案:

没有答案