Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/313.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 使用bcrypt编写自定义tomcat领域_Java_Authentication_Tomcat_Hsqldb_Bcrypt - Fatal编程技术网

Java 使用bcrypt编写自定义tomcat领域

Java 使用bcrypt编写自定义tomcat领域,java,authentication,tomcat,hsqldb,bcrypt,Java,Authentication,Tomcat,Hsqldb,Bcrypt,我正在开发一个基于Java的web应用程序,使用Tomcat7.0作为应用服务器。在得到了对的有用响应之后,我决定使用bcrypt在我的HSQLDB中安全地存储密码。但是Tomcat的默认领域实现不能处理bcrypt,所以我需要编写自己的;这是我编写自定义领域的唯一原因,尽管在所有其他方面,普通JDBCRealm都可以工作。我一直在谷歌上搜索并查看示例,但有几点我很困惑 首先,我应该扩展RealmBase还是JDBCRealm?我发现的大多数示例都使用RealmBase,但到目前为止,我已经成功

我正在开发一个基于Java的web应用程序,使用Tomcat7.0作为应用服务器。在得到了对的有用响应之后,我决定使用bcrypt在我的HSQLDB中安全地存储密码。但是Tomcat的默认领域实现不能处理bcrypt,所以我需要编写自己的;这是我编写自定义领域的唯一原因,尽管在所有其他方面,普通JDBCRealm都可以工作。我一直在谷歌上搜索并查看示例,但有几点我很困惑

首先,我应该扩展RealmBase还是JDBCRealm?我发现的大多数示例都使用RealmBase,但到目前为止,我已经成功地在应用程序中使用JDBCRealm(因为它仍在开发中,我开始以明文形式存储密码,并仅使用JDBCRealm来处理身份验证),并且一个建议的答案就是扩展它。不过,我不确定在这种情况下需要覆盖哪些方法。只是身份验证方法,还是其他什么?如果这样做了,JDBCRealm还能处理和管理用户角色、getPrincipal以及所有这些吗

其次,在上面链接的CodeRanch示例中,除非我遗漏了什么,否则getPassword方法似乎返回未加密的密码。因为我将要使用bcrypt,这是不可能的,而且我认为这似乎是不可取的。在其他类似的例子中,getPassword似乎只是直接从数据库返回密码。那么哪种方法是正确的呢?我找不到getPassword的确切用途;文件上没有说。只返回存储在数据库中的加密值就可以了吗


如果有人能告诉我应该扩展什么类,应该重写什么方法,以及应该返回什么getPassword,我将非常感激。

经过一些尝试和错误后,我找到了如何做到这一点。我扩展了JDBCRealm,只覆盖了authenticate方法,它工作得非常好。我把它放在与我的自定义域相同的目录中,下面的代码是有效的:

导入java.security.Principal;
导入org.apache.catalina.realm.JDBCRealm;
公共类BCryptRealm扩展了JDBCRealm
{
@凌驾
公共主体身份验证(字符串用户名、字符串凭据)
{
字符串hashedPassword=getPassword(用户名);
//在发现checkpw生成空指针后添加此检查
//如果hashedPassword为null,则会发生错误,当用户不使用时会发生此错误
//存在。我假设立即返回null将是一种不好的做法
//它会让攻击者知道哪些用户存在,哪些用户不存在,所以我补充说
//一个对hashpw的调用。不知道这是否完全解决了问题,所以如果
//您的应用程序有更严格的安全需求,这应该是
//进一步调查。
if(hashedPassword==null)
{
BCrypt.hashpw(“伪造密码”,BCrypt.gensalt());
返回null;
}
if(BCrypt.checkpw(凭证、哈希密码))
{
返回getPrincipal(用户名);
}
返回null;
}
}

您从哪里获得Bcrypt实现的?我不断收到错误,我不知道为什么,我使用了上面的代码,Tomcat现在调用此方法进行身份验证。
import java.security.Principal;
import org.apache.catalina.realm.JDBCRealm;
public class BCryptRealm extends JDBCRealm
{
  @Override
  public Principal authenticate(String username, String credentials)
  {
    String hashedPassword = getPassword(username);
    // Added this check after discovering checkpw generates a null pointer
    // error if the hashedPassword is null, which happens when the user doesn't
    // exist. I'm assuming returning null immediately would be bad practice as
    // it would let an attacker know which users do and don't exist, so I added
    // a call to hashpw. No idea if that completely solves the problem, so if
    // your application has more stringent security needs this should be
    // investigated further.
    if (hashedPassword == null)
    {
      BCrypt.hashpw("fakePassword", BCrypt.gensalt());
      return null;
    }
    if (BCrypt.checkpw(credentials, hashedPassword))
    {
      return getPrincipal(username);
    }
    return null;
  }
}