获取具有相同标识符值的其他对象已与会话Keycloak关联

时间:2019-07-01 20:43:46

标签: hibernate keycloak keycloak-services

我们正在尝试通过Keycloak对现有用户进行身份验证,因此实现了自定义SPI并将自定义SPI添加为用户联合身份

原因:javax.persistence.EntityExistsException:具有相同标识符值的另一个对象已与会话相关联:[org.keycloak.storage.jpa.entity.FederatedUserRoleMappingEntity#org.keycloak.storage.jpa.entity。 FederatedUserRoleMappingEntity $ Key @ e3a03493]

我们正在尝试使用Keycloak进行身份验证,并使用自定义提供程序来验证用户的详细信息,这些用户的详细信息位于使用存储提供程序SPI的自定义提供程序中

@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
    UserModel userModel = new UserAdapter(session, realm, model, repository.findUserByUsernameOrEmail(username));
    RoleModel roleModel = realm.getRole("user");
    userModel.grantRole(roleModel);
    return userModel;

}

添加“用户”角色时发生异常,并且当我不添加用户时,该用户尝试添加的领域具有角色“用户”。Web应用程序被重定向到用于添加用户的keycloak网页。 ... Realm containing the user role

新手使用keycloak的任何帮助将不胜感激

1 个答案:

答案 0 :(得分:1)

所以我只是在我们的自定义SPI中自己解决了这个问题。发生这种情况的原因是,缓存/数据库中已经有一个分配了此角色的用户。当您在Keycloak上使用表单登录时,它会多次调用SPI实现的接口,以便查找用户并将其缓存/存储在某个地方。

要解决此问题,您可以执行以下操作:

@Override
public UserModel getUserByUsername(String username, RealmModel realm) {
    UserModel userModel = new UserAdapter(session, realm, model, 
    repository.findUserByUsernameOrEmail(username));
    RoleModel roleModel = realm.getRole("user");

    //Change is here
    //---------------------------------------------------
    if (!userModel.getRoleMappings().contains(roleModel))
        userModel.grantRole(roleModel);
    //---------------------------------------------------        

    return userModel;
}

一旦调用grantRole方法,如果当前已将角色授予持久性用户,则将抛出EntityExistsException。这应该可以解决您的问题。