Jump to content

Configuring Symfony to authenticate to PostgreSQL using peer authentication


NotionCommotion

Recommended Posts

A while back, I was showed how to authenticate to PostgreSQL using peer authentication over a socket for applications where PHP, FPM, and PostgreSQL are all on the same machine.  All works.

I could use native PHP as shown and it returns results without errors so I know that PHP, FPM, and PostgreSQL is setup correctly to establish a connection using peer authentication without a PostgreSQL username or password.

$pdo = new PDO("pgsql:dbname=testing");
$rs = $pdo->query('SELECT * FROM company')->fetchAll();

I could also use Doctrine but not Symfony and get results without errors so I know that Doctrine is capable of establishing a connection using peer authentication without a PostgreSQL username or password.

$pdo = EntityManager::create(['driver' => 'pdo_pgsql','dbname' => 'testing'], Setup::createAnnotationMetadataConfiguration([__DIR__."/../src"], true, null, null, false))->getConnection();
$rs = $pdo->query('SELECT * FROM company')->fetchAll();

Now I am trying to do the same but when using Symfony.  I expected I could just edit config/packages/doctrine.yaml as follows, however, it results in An exception occurred in driver: SQLSTATE[08006] [7] fe_sendauth: no password supplied

doctrine:
    dbal:
        driver: pdo_pgsql
        dbname: testing
        server_version: 13

Any thoughts how to do this?  Thank you

Link to comment
Share on other sites

Okay, I got it working but it seems like a hack.  The following file creates a connection first without using Symfony and then with using Symfony.
 

<?php

use Doctrine\ORM\Tools\Setup;
use Doctrine\ORM\EntityManager;

use App\Kernel;
use Symfony\Component\Dotenv\Dotenv;
use Symfony\Component\ErrorHandler\Debug;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\DBAL\Connection;

ini_set('display_errors', 1);

require dirname(__DIR__).'/vendor/autoload.php';

function getPdowithoutSymfony():Connection
{
    $setup = Setup::createAnnotationMetadataConfiguration([__DIR__."/../src"], true, null, null, false);
    $em = EntityManager::create(['driver' => 'pdo_pgsql','dbname' => 'testing'], $setup);
    return $em->getConnection();
}

function getPdowithSymfony():Connection
{
    (new Dotenv())->bootEnv(dirname(__DIR__).'/.env');
    if ($_SERVER['APP_DEBUG']) {
        umask(0000);
        Debug::enable();
    }
    $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
    $kernel->boot();

    $em = $kernel->getContainer()->get('doctrine.orm.entity_manager');
    return $em->getConnection();
}

function test(Connection $pdo):int
{
    $stmt = $pdo->executeQuery('SELECT COUNT(*) FROM public.user');
    return $stmt->fetchColumn();    
}

echo('count without symfony: '.test(getPdowithoutSymfony()).PHP_EOL);
echo('count with symfony: '.test(getPdowithSymfony()).PHP_EOL);

 

Then in the following class I added the echo and var_dump lines:

<?php

namespace Doctrine\DBAL\Driver;

class PDOConnection extends PDO implements ConnectionInterface, ServerInfoAwareConnection
{
    public function __construct($dsn, $user = null, $password = null, ?array $options = null)
    {
        try {
            echo(get_class($this).PHP_EOL);
            var_dump(['$dsn'=>$dsn, '$user'=>$user, '$password'=>$password, '$options'=>$options, ]);
            parent::__construct($dsn, (string) $user, (string) $password, (array) $options);
            $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, [Statement::class, []]);
            $this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        } catch (PDOException $exception) {
            throw Exception::new($exception);
        }
    }
}

If I configure Symfony to use doctrine.dbal as {driver: pdo_pgsql,dbname: testing, server_version: 13}, I get:

\Doctrine\DBAL\Driver\__construct
Doctrine\DBAL\Driver\PDO\Connection
array(4) { ["$dsn"]=> string(21) "pgsql:dbname=testing;" ["$user"]=> NULL ["$password"]=> NULL ["$options"]=> array(0) { } }
count without symfony: 10

Doctrine\DBAL\Driver\PDO\Connection
array(4) { ["$dsn"]=> string(36) "pgsql:host=localhost;dbname=testing;" ["$user"]=> string(4) "root" ["$password"]=> NULL ["$options"]=> array(0) { } }
<!-- An exception occurred in driver: SQLSTATE[08006] [7] fe_sendauth: no password supplied (500 Internal Server Error) -->


So, then I configured Symfony to use doctrine.dbal as {driver: pdo_pgsql,dbname: testing, server_version: 13, user: null, host: null}, and no errors.

Doctrine\DBAL\Driver\PDO\Connection
array(4) { ["$dsn"]=> string(21) "pgsql:dbname=testing;" ["$user"]=> NULL ["$password"]=> NULL ["$options"]=> array(0) { } }
count without symfony: 10

Doctrine\DBAL\Driver\PDO\Connection
array(4) { ["$dsn"]=> string(21) "pgsql:dbname=testing;" ["$user"]=> NULL ["$password"]=> NULL ["$options"]=> array(0) { } }
count with symfony: 10

Zero documentation describing this as far as I could tell.  Anyone know whether there is a more proper way to do this?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.