如何查看我的数据库是否包含具有Hibernate给定用户名和密码的用户?

时间:2016-03-30 20:28:07

标签: hibernate jpa

我正在开发一个Web应用程序,其中包括一些使用Java EE 7和Hibernate的简单用户管理。我处于早期阶段,我目前正在编写持久层(?)。我需要编写一个方法来检查是否有用户具有给定的用户名和密码。 我的第一个想法是使用EntityManager的contains()方法,但是那个接收一个实体,因此它也将比较ID。但当然我的ID会自动增加,我不知道需要进行身份验证的给定用户的ID,所以它总是返回false。即使用户名和密码字段相等,ID字段也将始终不同。

这是我的第二个想法:

public boolean isUser(String username, String password) {
    Query query = getEntityManager().createNamedQuery("findUser");

    query.setParameter("username", username);
    query.setParameter("password", password);

    try {
       query.getResultList();
    } catch (NoResultException e) {
       return false;
    }
    return true;
}

这也失败了,因为由于某种原因它甚至没有引发NoResultException,即使结果列表的大小为0。

这是我最后的想法:

public boolean isUser(String username, String password) {
    Query query = getEntityManager().createNamedQuery("findUser");

    query.setParameter("username", username);
    query.setParameter("password", password);

    return query.getResultList().size() != 0;
}

这很有效,但我希望看看是否有更好的模式可以用Hibernate做这样的事情。提前谢谢!

2 个答案:

答案 0 :(得分:0)

出于安全原因,使用户名列不是唯一的,然后总是可以使用getSingleResult方法,这也绝不是一个好主意。同样出于性能原因,getResultList + size方法不是一个好主意,因为您必须仅为存在检查获取所有记录。我认为这也是一个设计失败,因为如果你可以让同一个用户拥有相同的密码,那么你如何识别正确的用户,因此GetSingleResult方法也可以用于非唯一的用户名。由于tip还会在会话bean中或直接在会话中保存用户实体,因为在Web应用程序中通常需要更多次实体信息,因此您不必多次查询用户数据。

就像尼古拉斯所说,如果你想使用JEE,那么看看像JAAS这样的所有功能。但它对你的容器有一点帮助,可以给你一个更好的答案。您还可以使用其他一些像PicketLink等框架。

答案 1 :(得分:0)

查找单个结果

您可以尝试Query#getSingleResult(),如下所示:

public User findUser(String username, String password) {

    Query query = getEntityManager().createNamedQuery("findUser");
    query.setParameter("username", username);
    query.setParameter("password", password);

    return (User) query.getSingleResult();
}

如果没有结果,上述方法将抛出NoResultException,如果有多个结果,则会抛出NonUniqueResultException

要记住,您必须永远将密码存储为数据库中的纯字符串。密码必须使用strong hashing functions进行编码。

Java EE安全

在谈论安全问题时,我想向您推荐另一种解决方案。我不知道你的要求,但似乎你正在重新发明轮子。除非你真的知道你在做什么,否则不要这样做。你有没有考虑过Java EE Security?

以下是一些很好的资源:

Spring Security

你的筹码中有春天吗?为什么不试试Spring Security

以下是一些资源: