对context.xml中有两个数据源的用户“root”@“localhost”的访问被拒绝

ppcbkaq5  于 2021-06-19  发布在  Mysql
关注(0)|答案(2)|浏览(598)

我在Java8、MySQLServer5.7.23、MySQLconnectorforJavaV5.1.45和TomcatV9.0.12(运行在ubuntu服务器18.04上)上遇到了一个问题。
我构建了一个简单的java应用程序(war),它在mysql数据库中执行查询。
我的context.xml(我放置了两个resources节点,一个用于生产,一个用于开发环境),从我从catalina中读取的实际应用程序场景中,选择一个名为“env”的参数,并用system.getproperty(“env”)读取它,应用程序可以选择要使用的适当数据源。

  1. <Context>
  2. <!-- MySQL - Production -->
  3. <Resource
  4. name="prod-jdbc/ds-1" auth="Container"
  5. type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
  6. driverClassName="com.mysql.jdbc.Driver"
  7. url="jdbc:mysql://localhost:3306/testdb?useSSL=false"
  8. username="dbuser" password="dbUserPwd!"
  9. autoReconnect="true" maxTotal="10"
  10. minIdle="3" maxIdle="5" maxActive="10" maxWaitMillis="10000"
  11. removeAbandonedOnBorrow="true" removeAbandonedOnMaintenance="true"
  12. logAbandoned="true" removeAbandonedTimeout="1000"
  13. closeMethod="close" testOnBorrow="true"
  14. testWhileIdle="true" timeBetweenEvictionRunsMillis="60000"
  15. validationQueryTimeout="10" validationInterval="6000"
  16. validationQuery="SELECT 1"
  17. />
  18. <!-- MySQL - Development -->
  19. <Resource
  20. name="dev-jdbc/ds-1" auth="Container"
  21. type="javax.sql.DataSource" factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
  22. driverClassName="com.mysql.jdbc.Driver"
  23. url="jdbc:mysql://localhost:3306/localdb?useSSL=false"
  24. username="root" password="root"
  25. autoReconnect="true" maxTotal="10"
  26. minIdle="3" maxIdle="5" maxActive="10"
  27. maxWaitMillis="10000" removeAbandonedOnBorrow="true"
  28. removeAbandonedOnMaintenance="true" logAbandoned="true"
  29. removeAbandonedTimeout="1000" closeMethod="close"
  30. testOnBorrow="true" testWhileIdle="true"
  31. timeBetweenEvictionRunsMillis="60000" validationQueryTimeout="10"
  32. validationInterval="6000" validationQuery="SELECT 1"
  33. />
  34. </Context>

一个简单的tester类:

  1. package main;
  2. import java.sql.Connection;
  3. import java.sql.ResultSet;
  4. import java.sql.SQLException;
  5. import java.sql.Statement;
  6. import javax.naming.Context;
  7. import javax.naming.InitialContext;
  8. import javax.naming.NamingException;
  9. import javax.servlet.ServletContextEvent;
  10. import javax.servlet.ServletContextListener;
  11. import javax.sql.DataSource;
  12. import javax.ws.rs.core.Application;
  13. public class ConnectionTester extends Application implements ServletContextListener {
  14. @Override
  15. public void contextInitialized(ServletContextEvent arg0) {
  16. Context ctx = null; Connection con = null; Statement stmt = null; ResultSet rs = null;
  17. try{
  18. ctx = new InitialContext();
  19. DataSource ds = (DataSource) ctx.lookup("java:/comp/env/prod-jdbc/ds-1");
  20. con = ds.getConnection();
  21. stmt = con.createStatement();
  22. rs = stmt.executeQuery("SELECT nome FROM Customers");
  23. while(rs.next()) {
  24. System.out.println(rs.getString("name"));
  25. }
  26. }
  27. catch(NamingException | SQLException e){
  28. e.printStackTrace();
  29. }
  30. finally{
  31. try {
  32. rs.close(); stmt.close(); con.close(); ctx.close();
  33. } catch (SQLException e) {
  34. System.out.println("Exception in closing DB resources");
  35. } catch (NamingException e) {
  36. System.out.println("Exception in closing Context");
  37. }
  38. }
  39. } // contextInitialized
  40. } // ConnectionTester

我已经这样设置了mysql权限(我还需要允许“dbuser”的外部访问,因为我有一个连接到这个mysql数据库的外部客户机):

  1. ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'veryStrongPwd';
  2. CREATE USER 'dbuser'@'localhost' IDENTIFIED BY 'dbUserPwd!';
  3. GRANT ALL PRIVILEGES ON *.* TO 'dbuser'@'localhost' WITH GRANT OPTION;
  4. GRANT ALL PRIVILEGES ON *.* TO 'dbuser'@'%' IDENTIFIED BY 'dbUserPwd!' WITH GRANT OPTION;
  5. FLUSH PRIVILEGES;

tomcat没有任何特定的配置或资源配置,只是将v9.0.12解压到一个文件夹中。
我尝试将“root”和“dbuser”凭据都放入context.xml中,但在启动tomcat时,出现以下问题:

  1. ConnectionPool.init Unable to create initial connections of pool.
  2. java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
  3. at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:965)
  4. at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)
  5. at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909)
  6. at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:873)
  7. at com.mysql.jdbc.MysqlIO.proceedHandshakeWithPluggableAuthentication(MysqlIO.java:1710)
  8. at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1226)
  9. ...

抛出这些例外之后,它会打印记录集,但是为什么即使在context.xml中设置了dbuser凭据,它也需要root登录呢?
我已经阅读了stackoverflow中的search,我已经阅读了我必须检查mysql.user表,如果我运行:

  1. SELECT user, host, plugin, authentication_string FROM mysql.user;

我得到这个(“plugin”列对每个记录都有“mysql\u native\u password”值):

如果我尝试使用以下命令从shell登录到mysql server:

  1. mysql -u root (or dbuser) -p

我可以成功登录。
编辑:我发现从context.xml中删除第二个“resource”节点(为开发环境创建的节点)后,问题就消失了,但我仍然不明白为什么会发生这种情况,因为在查找中我选择了prod资源(ctx.lookup(“java:/comp/env/prod jdbc/ds-1”)。
我错过了什么?提前谢谢

omqzjyyz

omqzjyyz1#

在你的 context.xml 你有 root 用户密码为 root . 在mysql脚本中,您设置了 root 用户密码 veryStrongPwd .
如果你的问题更多的是为什么即使你不使用 Resource -您正在将连接池的最小大小设置为 3 . 所以tomcat将创建连接池,并在启动时尝试向其中添加3个连接。也许你可以 minIdle0 你想怎么做就怎么做。
更新
还有另一个场景- initialSize 默认为10。将其设置为0将阻止tomcat在启动时尝试使用该数据源。

gt0wga4j

gt0wga4j2#

尝试检查用于连接的客户端的权限[ip]。有时,当您创建一个新的客户机,并在不是本地主机时从另一个终端进行连接时,需要特别说明。

相关问题