Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Play Framework 2存储用户密码哈希的最佳方法_Java_Playframework 2.0 - Fatal编程技术网

Java Play Framework 2存储用户密码哈希的最佳方法

Java Play Framework 2存储用户密码哈希的最佳方法,java,playframework-2.0,Java,Playframework 2.0,我的应用程序中有一个添加用户选项。我想在数据库中以哈希格式存储用户通行证。密码以纯文本格式存储在框架附带的示例代码中。 经过一些搜索,我发现在play2中实现了一个Crypto.encryptAES()函数,可用于保护密码 我的问题是什么地方使用它最好?以及如何使用它来创建最可维护的代码?我个人会在用户模型中这样做。我的字段有getter,因此在setPassword方法中: this.password = HashHelper.createPassword(password); Hashh

我的应用程序中有一个添加用户选项。我想在数据库中以哈希格式存储用户通行证。密码以纯文本格式存储在框架附带的示例代码中。 经过一些搜索,我发现在play2中实现了一个Crypto.encryptAES()函数,可用于保护密码


我的问题是什么地方使用它最好?以及如何使用它来创建最可维护的代码?

我个人会在
用户
模型中这样做。我的字段有getter,因此在
setPassword
方法中:

this.password = HashHelper.createPassword(password); 
Hashhelper
只是一个用于多用途散列的单例类

在Hashelper中,我使用BCrypt,只需在Build.scala中添加以下内容

org.mindrot" % "jbcrypt" % "0.3m
加密看起来像:

/**
 * Create an encrypted password from a clear string.
 * 
 * @param clearString
 *            the clear string
 * @return an encrypted password of the clear string
 * @throws AppException
 *             APP Exception, from NoSuchAlgorithmException
 */
public static String createPassword(String clearString) throws AppException {
    if (clearString == null) {
        throw new AppException("empty.password");
    }
    return BCrypt.hashpw(clearString, BCrypt.gensalt());
}
/**
 * Method to check if entered user password is the same as the one that is
 * stored (encrypted) in the database.
 * 
 * @param candidate
 *            the clear text
 * @param encryptedPassword
 *            the encrypted password string to check.
 * @return true if the candidate matches, false otherwise.
 */
public static boolean checkPassword(String candidate, String encryptedPassword) {
    if (candidate == null) {
        return false;
    }
    if (encryptedPassword == null) {
        return false;
    }
    return BCrypt.checkpw(candidate, encryptedPassword);
}
解密看起来像:

/**
 * Create an encrypted password from a clear string.
 * 
 * @param clearString
 *            the clear string
 * @return an encrypted password of the clear string
 * @throws AppException
 *             APP Exception, from NoSuchAlgorithmException
 */
public static String createPassword(String clearString) throws AppException {
    if (clearString == null) {
        throw new AppException("empty.password");
    }
    return BCrypt.hashpw(clearString, BCrypt.gensalt());
}
/**
 * Method to check if entered user password is the same as the one that is
 * stored (encrypted) in the database.
 * 
 * @param candidate
 *            the clear text
 * @param encryptedPassword
 *            the encrypted password string to check.
 * @return true if the candidate matches, false otherwise.
 */
public static boolean checkPassword(String candidate, String encryptedPassword) {
    if (candidate == null) {
        return false;
    }
    if (encryptedPassword == null) {
        return false;
    }
    return BCrypt.checkpw(candidate, encryptedPassword);
}

我喜欢让我的控制器尽可能简单,因为我认为我的控制器就像用户操作和业务模型(在我的模型内!)之间的交通控制器一样简单。

我在web上找到了一个更简单的解决方案,地址如下:

首先在下载jbcrypt-xxx.jar

在build.sbt中的libraryDependencies中,添加:

"org.mindrot" % "jbcrypt" % "0.3m"
此函数用于创建新用户(位于模型类用户中):

并且,仍然在用户类中,要进行身份验证的函数:

public static User authenticate(String userName, String password) {
    User user = User.find.where().eq("userName", userName).findUnique();
    if (user != null && BCrypt.checkpw(password, user.passwordHash)) {
      return user;
    } else {
      return null;
    }

它真的起作用了

我使用的是非常容易集成到应用程序中的。谢谢,但我真正想问的是在哪里调用哈希函数。在模型中还是在控制器中?如何使用?我的主要问题是,我不能在ebean.FWIW中使用
@PreUpdate
@Prepersist
,当用户更改密码或登录时,我在控制器中使用它(使用实用程序单例)。实用工具singleton目前使用的是
加密符号
,但将其换成其他符号就足够简单了。您能提供这些函数的示例吗?在控制器中更改窗体中字段的值时遇到问题。我想像
userForm.get().save()一样使用
.save()
并在保存之前更改
password
的值,但我只使用
get()
获取字段值。感谢您的详细回答,我也希望保持控制器干净,我认为这种逻辑应该在模型级别实现。我在某个地方读到,如果我为一个类创建了getter和setter,那么我必须为所有类的属性创建getter和setter。这是真的吗?虽然play可以处理公共属性,但我仍然更喜欢getter和setter,而且当混合使用它们时,我经历了奇怪的行为(值不可见)。但是对于getters,它总是有效的:-)我似乎有build.sbt,而不是build.scala。在这种情况下,正确的咒语是什么?谢谢回答得很好。如果我们使用build.sbt而不是build.scala,您能帮助我们做些什么吗?答案是。。libraryDependencies++=Seq(“org.mindrot”%“jbcrypt”%“0.3m”。。。