stablekernel / postgresql-dart

Dart PostgreSQL driver: supports extended query format, binary protocol and statement reuse.
https://www.dartdocs.org/documentation/postgres/latest
BSD 3-Clause "New" or "Revised" License
129 stars 32 forks source link

Azure PostgreSQL - Unsupported authentication type 3 #171

Open pedropastor opened 2 years ago

pedropastor commented 2 years ago

I am trying to connect to to an Azure Postgre database (not a virtual machine, the managed one, complete product name: Azure Database for PostgreSQL) and I keep getting this error. PostgreSQLSeverity.error : Unsupported authentication type 3, closing connection.

I have followed the code to here and here As suggested "I don't remember where" as I read too much documentation for this.

Apparently it is related to sending the password in Clear Text. But I get no clues what the heck the server is asking for (neither in microsoft documentation) The connection had been working perfectly in other development environment (virtual machine in AWS not RDS) but now we have to migrate for staging and deployment and are stuck with it. Note this environment is in a private cloud. The connection is being launched from a dart server running in kubernetes pod. Both the database and kubernetes are in the same private cluster and can reach each other via internal VLAN.

Any suggestions how to deal with this? Anyone had the same issue and fixed it?

pedropastor commented 2 years ago

Wow, Really don't understand how, but I fixed it.

Added a new authenticator case on connection_fsm.dart

         case AuthenticationMessage.KindClearTextPassword:
          _authenticator =
              createAuthenticator(connection!, AuthenticationScheme.CLEAR);
          continue authMsg;

And the authenticator:

class ClearAuthenticator extends PostgresAuthenticator{
  ClearAuthenticator(PostgreSQLConnection connection) : super(connection);

  @override
  void onMessage(AuthenticationMessage message) {
    final authMessage = ClearMessage(connection.password!);
    connection.socket!.add(authMessage.asBytes());
  }

}
class ClearMessage extends ClientMessage {
  UTF8BackedString? _authString;

  ClearMessage(String password) {
    _authString = UTF8BackedString(password);
  }

  @override
  void applyToBuffer(ByteDataWriter buffer) {
    buffer.writeUint8(ClientMessage.PasswordIdentifier);
    final length = 5 + _authString!.utf8Length;
    buffer.writeUint32(length);
    _authString!.applyToBuffer(buffer);
  }
}

Now it can connect properly.

Not sure of the implications this has, it may be insecure? I really don't deeply understand all this. Would you like me to make a pull request to add this feature? Actually, do you want to add this feature?

How is the process? this would be my first contribution to any repository ever.