mariadb-corporation / mariadb-connector-nodejs

MariaDB Connector/Node.js is used to connect applications developed on Node.js to MariaDB and MySQL databases. MariaDB Connector/Node.js is LGPL licensed.
GNU Lesser General Public License v2.1
363 stars 93 forks source link

AWS RDS Signer with mariadb, IAM authentication, is there a way to change mysql password connection method? #246

Closed Mikael-Kolehmainen closed 1 year ago

Mikael-Kolehmainen commented 1 year ago

I'm creating a pool with mariadb, is there a way to change the default mysql_native_password password connection method to mysql_clear_password?

I checked this issue but it's old, used in mysql2 package and authPlugins property doesn't seem to exist anymore.

Here's my code to give you an idea of what I'm trying to achieve:

const getDbPool = async () => {
  /** @type {import('@aws-sdk/rds-signer').SignerConfig} */
  const signerOptions = {
    region: "eu-west-1",
    hostname: process.env.InteractiveInvoice,
    port: 3306,
    username: process.env.InteractiveInvoiceDbUser
  };

  const rdsSigner = new Signer(signerOptions);
  const rdsToken = await rdsSigner.getAuthToken();

  /** @type {mariadb.PoolConfig} */
  const mariadbConfig = {
    host: process.env.InteractiveInvoice,
    user: process.env.InteractiveInvoiceDbUser,
    password: rdsToken,
    database: process.env.InteractiveInvoiceDb,
  };

  console.log(mariadbConfig);

  return mariadb.createPool(mariadbConfig);
};
rusher commented 1 year ago

There is no solution for now, but some solution might be implemented.

I don't think changing authentication plugins is a good idea there, this is normally use when server is specifically asking for a non-standard authentication plugin.

My first thought would be to allow providing a function as a password, something like :

const getDbPool = async () => {
  /** @type {import('@aws-sdk/rds-signer').SignerConfig} */
  let lastToken;
  let lastTokenTimeout;

  const getOrGenerateToken = async () => {
      if (lastTokenTimeout && lastTokenTimeout > Date.now()) return lastToken;

      const signerOptions = {
        region: "eu-west-1",
        hostname: process.env.InteractiveInvoice,
        port: 3306,
        username: process.env.InteractiveInvoiceDbUser
      };

      const rdsSigner = new Signer(signerOptions);
      lastToken = await rdsSigner.getAuthToken();
      lastTokenTimeout = Date.now() + 14 * 3600 * 1000;
      return lastoken;
  }

  /** @type {mariadb.PoolConfig} */
  const mariadbConfig = {
    host: process.env.InteractiveInvoice,
    user: process.env.InteractiveInvoiceDbUser,
    password: getOrGenerateToken,
    database: process.env.InteractiveInvoiceDb,
  };

  console.log(mariadbConfig);

  return mariadb.createPool(mariadbConfig);
};
Mikael-Kolehmainen commented 1 year ago

Thank you for your answer!

Do you have any ideas on how I could achieve a successful connection to a MariaDB RDS instance with password and IAM authentication? I got it working with a normal MariaDB user with only password authentication but IAM would be crucial.

Mikael-Kolehmainen commented 1 year ago

Our team decided on using a normal database user instead of an IAM user because also of some other limitations with the IAM database authentication. I will close this issue now as unresolved.

rusher commented 1 year ago

Still, this is some improvement to have, this will probably go in next version