0

I'm using Spring Boot App which is deployed on Cloud Run (GCP). The app is establishing the database connection through Cloud SQL Proxy using IAM authentication.

The goal is to implement Unix Socket Connection instead of TCP for connecting with Cloud SQL. Bellow is the application.yml content:

spring:
    cloud:
        gcp:
            sql:
                jdbc:
                    enabled: false
                database-name: db-name
                enable-iam-auth: true
                instance-connection-name: instance-name
    datasource:
        url: jdbc:postgresql:///db-name?unixSocketPath=/cloudsql/instance-name/.s.PGSQL.5432&socketFactory=com.google.cloud.sql.postgres.SocketFactory&enableIamAuth=true&sslmode=disable&cloudSqlInstance=instance-name
        username: my-username
        password: ""
        type: com.zaxxer.hikari.HikariDataSource
        hikari:
            maximum-pool-size: 10

After the deployment in the logs I got an info message: "Connecting to Cloud SQL instance [instance-name] via unix socket at..." which makes sense because the unixSocketPath property is provided in JDBC URL.

The error that I'm getting is that password is not provided (but I'm using IAM auth so the password is not needed). Here is the complete stack trace:

org.postgresql.util.PSQLException: The server requested password-based authentication, but no password was provided by plugin null
    at org.postgresql.core.v3.AuthenticationPluginManager.lambda$withEncodedPassword$0(AuthenticationPluginManager.java:110)
    at org.postgresql.core.v3.AuthenticationPluginManager.withPassword(AuthenticationPluginManager.java:81)
    at org.postgresql.core.v3.AuthenticationPluginManager.withEncodedPassword(AuthenticationPluginManager.java:107)
    at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:691)
    at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:180)
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:235)
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49)
    at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:223)
    at org.postgresql.Driver.makeConnection(Driver.java:402)
    at org.postgresql.Driver.connect(Driver.java:261)
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138)
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364)
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206)
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476)
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561)
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115)
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112)
    at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:68)
    at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator.initiateService(JdbcEnvironmentInitiator.java:35)
    at org.hibernate.boot.registry.internal.StandardServiceRegistryImpl.initiateService(StandardServiceRegistryImpl.java:101)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.createService(AbstractServiceRegistryImpl.java:263)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:237)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.id.factory.internal.DefaultIdentifierGeneratorFactory.injectServices(DefaultIdentifierGeneratorFactory.java:175)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.injectDependencies(AbstractServiceRegistryImpl.java:286)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.initializeService(AbstractServiceRegistryImpl.java:243)
    at org.hibernate.service.internal.AbstractServiceRegistryImpl.getService(AbstractServiceRegistryImpl.java:214)
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.<init>(InFlightMetadataCollectorImpl.java:173)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:127)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:1460)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1494)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1154)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:908)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:745)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:420)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:307)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1317)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
    at com.glopal.ms.glfbconnector.FacebookConnectorApplication.main(FacebookConnectorApplication.java:14)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:108)
    at org.springframework.boot.loader.Launcher.launch(Launcher.java:58)
    at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)

Any ideas how to solve this issue?

P.S. If I remove JDBC URL and enable GCP SQL Auto-Configuration everything works fine but the idea is to use unix-socket connection instead of TCP.

Update (Dependencies):

<dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-dependencies</artifactId>
        <version>${spring-cloud.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>spring-cloud-gcp-dependencies</artifactId>
        <version>${spring-cloud-gcp.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
      <dependency>
        <groupId>com.google.cloud</groupId>
        <artifactId>libraries-bom</artifactId>
        <version>${gcp-libraries.version}</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  • Spring Cloud version: 2021.0.2
  • Spring GCP version: 3.4.7
  • GCP libraries version: 25.3.0

References:

Heril Muratovic
  • 1,940
  • 6
  • 25
  • 46

3 Answers3

0

As mentioned in this github, you have to set non-empty string value to password field in the properties, otherwise it will fail at driver level validation.

Note: a non-empty string value for the password property must be set. While this property will be ignored when connecting with the Cloud SQL Connector using IAM auth, leaving it empty will cause driver-level validations to fail.

Roopa M
  • 2,171
  • 4
  • 12
  • I've already try that but I'm getting the same error. – Heril Muratovic Apr 28 '23 at 10:07
  • 1
    @HerilMuratovic Can you share minimal reproducible steps and also share dependencies your using – Roopa M Apr 28 '23 at 10:13
  • question is updated with additional info. – Heril Muratovic Apr 28 '23 at 10:19
  • @HerilMuratovic Can you try running `gcloud auth application-default login`? reference: https://github.com/JoeWang1127/cloudsql-iam-demo – Roopa M Apr 28 '23 at 11:22
  • Yes, command is working. Also, connection without providing custom jdbc url is working correctly. But, that's not the goal. The goal is to have unix socket connection working with IAM auth. – Heril Muratovic Apr 28 '23 at 11:32
  • can you try running `gcloud auth print-access-token` and make sure that the token looks valid? check if they are any special character – Roopa M Apr 28 '23 at 12:44
  • Additionally, 1) make sure the IAM user is added to the database before you start. 2) You must ensure that the user you use to log in is the same as the email you are using; for example, if your IAM user is "xyz@gmail.com," you must enter that as your db_username – Roopa M Apr 28 '23 at 12:47
  • 1) Everything is good with IAM user 2) also good. Access token is valid... I have tried IAM auth couple times and it works. The problem occurred when I added unixSocketPath property – Heril Muratovic Apr 28 '23 at 14:29
  • 1
    I suggest you to contact [google support](https://cloud.google.com/support-hub), they may have more insight on your issue – Roopa M May 01 '23 at 06:26
0

Re-posting my response from the issue.

If you're using the Cloud SQL JDBC Socket Factory, there's no need to use the built-in Cloud SQL Proxy integration with Unix Sockets.

Just remove the unix socket configuration and you'll be good.

enocom
  • 1,496
  • 1
  • 15
  • 22
0

Cloud SQL Team has provided a workaround for the issue, which consists of using the latest version of the Java connector that has a fix applied.

Release notes can be found on this link: https://github.com/GoogleCloudPlatform/cloud-sql-jdbc-socket-factory/releases

Fix is applied in version v1.11.1.

If you're using Spring Cloud GCP Dependency (like I am in this project) you can find release notes on this link: https://github.com/GoogleCloudPlatform/spring-cloud-gcp/releases. Versions v3.5.1 and v4.3.1 use the proper Java Connector with fixed issue.

This means that you don't need any custom data source configuration, just use YML props as before:

spring:
  cloud:
    gcp:
      sql:
        database-name: db-name
        enable-iam-auth: true
        instance-connection-name: instance-name
  datasource:
    hikari:
      maximum-pool-size: 10
    type: com.zaxxer.hikari.HikariDataSource
    username: usr
Heril Muratovic
  • 1,940
  • 6
  • 25
  • 46