How to use custom authenticator to authenticate from database?

15 days ago

+
0
-

I am setting up Authentication from database using example from https://doc.nette.org/…cess-control
The database connection works fine, but the custom authenticator is not found.
The file which contains the custom authenticator is located in app/Model/SiteAuthenticator.php

My config.neon file contains:

services:
        authenticator: App\Model\SiteAuthenticator
        router: App\Router\RouterFactory::createRouter

The app/Model/SiteAuthenticator.php looks like this:

<?php

namespace App\Model\SiteAuthenticator;

use Nette\Security\Passwords;
use Nette\Security\IAuthenticator;

class SiteAuthenticator implements IAuthenticator
{
        public function __construct(Nette\Database\Context $database, Nette\Security\Passwords $passwords)
        {
                $this->database = $database;
                $this->passwords = $passwords;
        }

        public function authenticate(array $credentials): Nette\Security\IIdentity
        {
                [$username, $password] = $credentials;

                $row = $this->database->table('users')
                        ->where('username', $username)->fetch();

                if (!$row) {
                        throw new Nette\Security\AuthenticationException('User not found.');
                }

                if (!$this->passwords->verify($password, $row->password)) {
                        throw new Nette\Security\AuthenticationException('Invalid password.');
                }

                return new Nette\Security\Identity($row->id, $row->role, ['username' => $row->username]);
        }
}

?>

The error I am getting is:

Nette\DI\ServiceCreationException
Service 'authenticator': Class App\Model\SiteAuthenticator not found.

Last edited by kevin.waterson@gmail.com (2019-11-26 20:44)

15 days ago

Mabar
Member | 177
+
0
-

namespace App\Model\SiteAuthenticator + class SiteAuthenticatorApp\Model\SiteAuthenticator\SiteAuthenticator

15 days ago

+
0
-

Thanks Mabar, a little closer, except I now get an error

Compile Error
Declaration of App\Model\SiteAuthenticator\SiteAuthenticator::authenticate(array $credentials): App\Model\SiteAuthenticator\Nette\Security\IIdentity must be compatible with Nette\Security\IAuthenticator::authenticate(array $credentials): Nette\Security\IIdentity

My SiteAuthenticator class looks like this:

<?php

namespace App\Model\SiteAuthenticator;

use Nette\Security\IIdentity;
use Nette\Security\Passwords;
use Nette\Security\IAuthenticator;

class SiteAuthenticator implements IAuthenticator
{
        public function __construct(Nette\Database\Context $database, Nette\Security\Passwords $passwords)
        {
                $this->database = $database;
                $this->passwords = $passwords;
        }

        public function authenticate(array $credentials): Nette\Security\IIdentity
        {
                [$username, $password] = $credentials;

                $row = $this->database->table('users')
                        ->where('username', $username)->fetch();

                if (!$row) {
                        throw new Nette\Security\AuthenticationException('User not found.');
                }

                if (!$this->passwords->verify($password, $row->password)) {
                        throw new Nette\Security\AuthenticationException('Invalid password.');
                }

                return new Nette\Security\Identity($row->id, $row->role, ['username' => $row->username]);
        }
}
?>

15 days ago

Mabar
Member | 177
+
+1
-

public function authenticate(array $credentials): Nette\Security\IIdentity – you are using relative namespace to your actual namespace, it's a App\Model\SiteAuthenticator + Nette\Security\IIdentity.

You should either use use use Nette\Security\IIdentity; with IIdentity or just absolute namespace \Nette\Security\IIdentity

15 days ago

CZechBoY
Member | 3430
+
0
-

There is alredy use for that – just write

 public function authenticate(array $credentials): IIdentity

as i check whole code im thinking about importing only Nette namespace, you use full ns path everywhere…
use Nette

btw check some tutorial for php oop as this is not much related to framework itself

Last edited by CZechBoY (2019-11-26 23:55)

15 days ago

+
0
-

Thanks Mabar, the working code for the Authenticator class is:

<?php

namespace App\Model\SiteAuthenticator;

use \Nette\Security\IIdentity;
use \Nette\Security\Passwords;
use \Nette\Security\IAuthenticator;

class SiteAuthenticator implements IAuthenticator
{
        public function __construct(\Nette\Database\Context $database, \Nette\Security\Passwords $passwords)
        {
                $this->database = $database;
                $this->passwords = $passwords;
        }

        public function authenticate(array $credentials): \Nette\Security\IIdentity
        {
                [$username, $password] = $credentials;

                $row = $this->database->table('users')
                        ->where('username', $username)->fetch();

                if (!$row) {
                        throw new Nette\Security\AuthenticationException('User not found.');
                }

                if (!$this->passwords->verify($password, $row->password)) {
                        throw new Nette\Security\AuthenticationException('Invalid password.');
                }

                return new Nette\Security\Identity($row->id, $row->role, ['username' => $row->username]);
        }
}
?>