使用bcrypt编写自定义tomcat域

我正在使用Tomcat 7.0作为应用程序服务器开发基于Java的Web应用程序.在对a prior question的有用回复之后,我决定使用bcrypt在我的HSQLDB中安全地存储密码.但是Tomcat的默认Realm实现无法处理bcrypt,所以我需要编写自己的;这是我写一个自定义领域的唯一原因,尽管在其他所有方面都可以使用JDBCRealm.我一直在谷歌搜索并查看示例,我对两点感到困惑.

首先,我应该扩展RealmBase还是JDBCRealm?我发现的大多数例子都使用了RealmBase,但到目前为止我已成功使用JDBCRealm作为应用程序(因为它仍在开发中,我开始将密码存储在纯文本中,只是使用JDBCRealm来处理身份验证),并且一个答案是建议question on Code Ranch扩展一下.不过,我不确定在这种情况下我需要覆盖哪些方法.只是验证方法,还是更多?如果这样做,JDBCRealm仍然能够处理和管理用户角色,getPrincipal,以及所有这些?

其次,在上面链接的CodeRanch示例中,除非我遗漏了某些内容,否则getPassword方法似乎返回了未加密的密码.因为我将要使用不可能的bcrypt,而且无论如何它似乎都是不可取的,我想.在blog post这样的其他示例中,getPassword似乎只是直接从数据库返回密码.那么哪种方式是正确的?我找不到getPassword的用途;文档没有说.为此可以返回存储在数据库中的加密值吗?

如果有人能告诉我应该扩展哪个类,我应该覆盖哪些方法,以及getPassword应该返回什么,我真的很感激.

最佳答案
经过一些试验和错误,我想出了如何做到这一点.我扩展了JDBCRealm并且只覆盖了authenticate方法并且它完美地工作.我将BCrypt.java放在与我的自定义域相同的目录中,这段代码是有用的:

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

相关文章

摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠...
今天犯了个错:“接口变动,伤筋动骨,除非你确定只有你一个...
Writer :BYSocket(泥沙砖瓦浆木匠)微 博:BYSocket豆 瓣:...
本文目录 线程与多线程 线程的运行与创建 线程的状态 1 线程...