Vlastní authenticator dědící od Nette\Security\SimpleAuthenticator

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
jEhLa
Člen | 70
+
0
-

Zdravím,
řeším jak v config.neon nastavit vlastní authenticator s přístupem k db, ale rád bych zachoval i nastavení pro výchozí SecurityExtension s SimpleAuthenticator v sekci:

security:
	users:
		username:
			password: password
			roles: [admin]
Idea byla taková že si podědím SimpleAuthenticator, který bude v constructoru kromě výchozího $userlist požadovat i přístup k databázi. A v config.neon nastavím:
services:
	security.authenticator:
		class: App\Security\Authenticator

Avšak to vyhodí chybu:
Parameter $userlist in App\Security\Authenticator::__construct() has no class type hint or default value, so its value must be specified.

Protože nastavením class, nebo factory v configu, přepíšu nastavení provedené SecurityExtension.

Co s tím? Jak zachovat, aby se mému vlastnímu authenticatoru předal jak seznam uživatelů definovaných v security, tak přístup k db?

Děkuji za Vaši pozornost. :-)

jEhLa
Člen | 70
+
0
-

Moje nápady:

  • Můžu to nastavení přesunout ze sekce security do parameters a předat ji službě, ale tím se odstřihnu od možnosti využít SecurityExtension, které mi na to co potřebuji stačí, jen bych potřeboval i přístup do db.
  • Nebo podědit SecurityExtension a udělat si novou sekci v configu, třeba AppSecurity. Ale to se mi zdá zbytečné, pro můj účel.

Je ještě nějaká jiná možnost?

CZechBoY
Člen | 3608
+
+3
-

Zkus kompozici – vyžádat SimpleAuthenticator v tom tvém autentikátoru a jako fallback potom tahat data z databáze.

private $simpleAuthenticator;

public function __construct(SimpleAuthenticator $simpleAuthenticator)
{
	$this->simpleAuthenticator = $simpleAuthenticator;
}

public function login(array $credentials)
{
	try {
		$result = $this->simpleAuthenticator->login($credentials);
	} catch (AuthenticationException $e) {
		$result = $this->authenticateDb($credentials);
	}

	return $result;
}

private function authenticateDb(array $credentials)
{
	return $this->db->query(...)->fetch(); // nebo tak něco
}

Editoval CZechBoY (15. 11. 2016 17:47)

jEhLa
Člen | 70
+
0
-

@CZechBoY: Díky za rychlou odpověď.

To bych pak ale musel přepsat i Nette\Security\User na nějaký vlastní, protože vyžaduje IAuthenticator. A kdybych to udělal takto, tak bych měl dvě služby IAuthenticator. Nebo by ten můj Authenticator neimplementoval rozhraní IAuthenticator? A všude bych v závislostech požadoval přímo ten můj jako App\Security\Authenticator? Tak jsi to myslel?

CZechBoY
Člen | 3608
+
0
-

V konfiguraku sluzeb uved tvoji finalni implementaci IAuthenticatoru jako si psal v uvodnim prispevku.

jEhLa
Člen | 70
+
0
-

To spadne ale právě na:
Service ‚security.authenticator‘: Service of type Nette\Security\SimpleAuthenticator needed by App\Security\Authenticator::__construct() not found.

Jak bych ho mohl chtít předat, když tím že to přepíšu v configu se ani nevytvoří.

Ale funguje to když jsem vytvořil tedy dvě služby IAuthenticator. Nechám vytvořit SimpleAuthenticator a vytvořím si ten můj App\Security\Authenticator, kterému předám ten Simple. Musel jsem ale ještě nastavit jiný Nette\Security\User aby nepožadoval IAuthenticator ale přímo App\Security\Authenticator.

Ale moc spokojený s tím nejsem, že mám vytvořené dvě služby IAuthenticator :-/

David Matějka
Moderator | 6445
+
+2
-

User nemusis upravovat, staci, ze u toho security.authenticator vypnes autowiring

CZechBoY
Člen | 3608
+
0
-

Případně to zkus takhle https://github.com/…uthenticator

Editoval CZechBoY (15. 11. 2016 19:55)

jEhLa
Člen | 70
+
0
-

@DavidMatějka No joo, taky pravda. To bude asi nejlepší.

@CZechBoY Na to už jsem koukal dřív, ale nechtěl jsem dál v aplikaci řešit který authenticator chci použít.

Po vypnutí autowiring, jsem s tím docela spokojen.

Děkuji Vám moc za pomoc (y).