'Tomcat connecting to MariaDB using TLS throws javax.naming.NamingException; command line connection works properly
I'm using Tomcat 7 on web host foo connecting to MariaDB 5.5.56 on database host bar, using user bob. All systems are running CentOS 7. Initially this connection used password based authentication.
Now there is a requirement to encrypt the connection with TLS. I have a certificate and key file for each host foo and bar. I have configured MariaDB to use these; the my.cnf file on the database host contains these relevant lines:
[mysqld]
ssl-ca=/etc/pki/ca.crt
ssl-cert=/etc/pki/bar.crt
ssl-key=/etc/pki/bar.key
I have confirmed within MariaDB that TLS is enabled. I have also confirmed that all remote connections have ssl_type set to X509.
I am able to connect to the database on the command line from the web host:
user@foo > mysql -h bar -u bob -p --ssl-ca=/etc/pki/ca.crt --ssl-key=/etc/pki/foo.key --ssl-cert=/etc/pki/foo.crt
So far, this proves that the certificates are correct, and that bob has access to the database.
The Tomcat config server.xml contains this connector:
<Connector port="443"
protocol="org.apache.coyote.http11.Http11Protocol"
maxThreads="500"
SSLEnabled="true"
scheme="https"
secure="true"
keystoreFile="/etc/pki/foo.jks"
keystorePass="abcde"
truststoreFile="/etc/pki/trust"
truststorePass="zzgo"
clientAuth="false"
sslProtocol="TLS" />
Using keytool, I have verified that the passwords match the store files. (Of course, the passwords shown here are fake.)
I have added the proper <security-constraint> to Tomcat's web.xml.
According to all my research, these settings should enable Tomcat to connect to MariaDB using these certs and store files. However, when connecting to a servlet Data that communicates with the database, the log shows exceptions like this:
SEVERE: Allocate exception for servlet Data
javax.naming.NamingException: Access denied for user 'bob'@'foo' (using password: YES)
at org.apache.naming.NamingContext.lookup(NamingContext.java:865)
...
at org.hibernate.connection.DatasourceConnectionProvider.configure(DatasourceConnectionProvider.java:75)
at org.hibernate.connection.ConnectionProviderFactory.newConnectionProvider(ConnectionProviderFactory.java:137)
...
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:360)
... and so on
The error indicates that something in the database connection is incorrect; whether it's a Tomcat setting, the stores, or something else is more than I have been able to determine.
Edit 1
I have confirmed that the fingerprint of foo.crt matches the fingerprint of the certificate stored in foo.jks.
Edit 2
I made a test application using the same Properties entries. The test app DOES connect using TLS. Therefore, as suggested, the issue resides somewhere in the JDBC
As far as I can tell, there's only one difference: The real app converts the Properties object to a PoolConfiguration object using DataSourceFactory.parsePoolProperties(). Then I try to debug this using poolProperties.getConnectionProperties(), but the resulting string is null. I'm trying to find other ways to debug the pool properties.
Solution 1:[1]
You are advised to add parameters in JDBC
useSSL=true&trustServerCertificate=true&requireSSL=true
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | 90linux |
