1
votes

I am looking for some tips how I can configure a DataSourceRealm with an MySQL database including bcrypt-hashed passwords. Unfortunately, I am already struggling with getting the DataSource running - even with clear text passwords.

I have edited the conf/context.xml and added the DataSource as follows:

<Context>
[...]
<Resource name="jdbc/MYRESOURCE" auth="Container" type="javax.sql.DataSource"
maxTotal="100" maxIdle="30" maxWaitMillis="10000"
username="USER" password="PASSWORD" driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://my.database.com:3306/DATABASE?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=UTC&amp;verifyServerCertificate=false&amp;useSSL=true&amp;requireSSL=true&amp;autoReconnect=true" />
</Context>

The server.xml contains the Realm as follows:

<Realm className="org.apache.catalina.realm.DataSourceRealm"
dataSourceName="jdbc/MYRESOURCE"
userTable="myuser" userNameCol="username" userCredCol="password"
userRoleTable="myuser_roles" roleNameCol="role"/>

When I start the Tomcat, it says that my context "jdbc/MYRESOURCE" is not found.

I also tried to add another to the conf/context.xml which results in the Tomcat is not starting at all. Also same, if I add the into the of the conf/server.xml

What is wrong here? Can somebody help?

2
Try putting the resource in the <GlobalNamingResources> block of your server.xml.Piotr P. Karwasz
Hi Piotr, Thanks! That is working now for clear text passwords. How can I add the bcrypt-hash now? Is it supported by the CredentialHandler?Peter_O

2 Answers

1
votes

Concerning the plaintext part, you declare your JDBC <Resource> at a webapp context, so:

  • either declare the <Realm> in the same context with a localDataSource="true",
  • or declare the JDBC Resource globally inside <GlobalNamingResources>.

Concerning bcrypt: none of the two credential handlers in Tomcat (MessageDigestCredentialHandler and SecretKeyCredentialHandler) supports either the format used by bcrypt or the password hashing. If you want reuse hashed passwords from another source, it won't be possible without writing your own CredentialHandler.

The only storage formats supported are:

  • plainText - the plain text credentials if no algorithm is specified
  • encodedCredential - a hex encoded digest of the password digested using the configured digest
  • {MD5}encodedCredential - a Base64 encoded MD5 digest of the password
  • {SHA}encodedCredential - a Base64 encoded SHA1 digest of the password
  • {SSHA}encodedCredential - 20 character salt followed by the salted SHA1 digest Base64 encoded
  • salt$iterationCount$encodedCredential - a hex encoded salt, iteration code and a hex encoded credential, each separated by $

(source Tomcat documentation)

However the supported hashing functions are similar to bcrypt, so you can use, e.g.:

<Realm className="org.apache.catalina.realm.DataSourceRealm"
       dataSourceName="jdbc/MYRESOURCE"
       userTable="myuser"
       userNameCol="username"
       userCredCol="password"
       userRoleTable="myuser_roles"
       roleNameCol="role">
    <CredentialHandler class="org.apache.catalina.realm.SecretKeyCredentialHandler" />
</Realm>

and have a format as secure as bcrypt.

You can hash your passwords using:

$CATALINA_HOME/bin/digest.sh -h org.apache.catalina.realm.SecretKeyCredentialHandler <your_password>

from the command line, where $CATALINA_HOME is Tomcat's directory.

0
votes

After some research I found a custom integration on GitHub, which supports bcrypt passwords.

I just put the JAR into the 'lib' directory and switched the standard "MessageDigestCredentialHandler" to the new "BCryptoCredentialHandler" as described on GitHub.

https://github.com/andreacomo/tomcat-bcrypt/