How to specify trusted authentication method for Postgresql?
keithrbennett opened this issue · 2 comments
I am porting a Rails 6 Postgres app to JRuby and am getting the following error when trying to perform a DB operation such as rails db:reset
:
rails aborted!
ActiveRecord::JDBCError: The server requested password-based authentication, but no password was provided.
arjdbc/jdbc/RubyJdbcConnection.java:529:in `initialize'
/home/kbennett/.rvm/gems/jruby-9.2.13.0/gems/activerecord-jdbc-adapter-60.2-java/lib/arjdbc/abstract/core.rb:21:in `initialize'
...
/home/kbennett/.rvm/gems/jruby-9.2.13.0/gems/railties-6.0.3.3/lib/rails/commands.rb:18:in `<main>'
bin/rails:9:in `<main>'
Caused by:
Java::OrgPostgresqlUtil::PSQLException: The server requested password-based authentication, but no password was provided.
org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:545)
...
In MRI Ruby it works fine. For MRI, in database.yml
I specify postgresql
as the adapter; for JRuby, jdbcpostgresql
. That is the only change I made in database.yml
.
default: &default
adapter: jdbcpostgresql
encoding: unicode
# For details on connection pooling, see Rails configuration guide
# https://guides.rubyonrails.org/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: my_database
I think this configuration results in Postgres using "trust" (or is it "peer"?) authentication in MRI, but "password" authentication in JRuby? Why is this, and is there a way to specify "trust" (or "peer"?) authentication with JRuby?
(A description of Postgresql authentication methods is at https://www.postgresql.org/docs/9.1/auth-methods.html.)
Poking around it seems like you should be able to just pass a blank password and it will work, but you will need to make sure the database is set up to trust local IP connections. I believe by default trust is only allowed on local unix sockets.
I think this is more a question of how to do pg "trust" authentication with JDBC, so look around from that perspective.
Thanks, Charlie. For my purposes, I think I'd prefer to specify the username and password rather than change DB settings.
I have this in my Gemfile:
IS_JRUBY = (RUBY_PLATFORM == 'java')
if IS_JRUBY
ruby '2.5.7'
gem 'activerecord-jdbc-adapter', '>= 60.2'
gem 'activerecord-jdbcpostgresql-adapter'
else
ruby '2.7.1'
gem 'pg', '>= 0.18', '< 2.0'
end
...and this in my database.yml:
<% IS_JRUBY = (RUBY_PLATFORM == 'java') %>
default: &default
adapter: <%= IS_JRUBY ? 'jdbcpostgresql' : 'postgresql' %>
and this in my database.yml development and test environment sections:
<% if IS_JRUBY %>
username: <%= `whoami` %>
password: <%= ENV.fetch('POSTGRES_PW') { 'password' } %>
<% end %>
Does that seem like a reasonable solution? (I do have to rerun bundle
when switching Ruby implementations.) Is there a better way to do this?