ACL – ROLE isAllowed vrací false
- motorcb
- Člen | 552
Zdravím,
stále zápasím s ACL.
Uživatele přihlašuji takto:
return new Security\Identity( $userObject->id, array( "registered" ), $user );
Ovšem mi stále vrací false (přitom role je na tvrdo nastavená na „registered“):
dump( $this->getUser()->isAllowed( 'pool', 'add' ) );
dump( $this->getUser() );
:
Nette\Security\User #02e8
guestRole => "guest" (5)
authenticatedRole => "authenticated" (13)
onLoggedIn => NULL
onLoggedOut => NULL
storage private => Nette\Http\UserStorage #3159
namespace private => ""
sessionHandler private => Nette\Http\Session #31c1
regenerated private => NULL
options private => array (14) [ ... ]
request private => Nette\Http\Request #8340 { ... }
response private => Nette\Http\Response #e7da { ... }
sessionSection private => NULL
authenticator private => App\Model\Authenticator #51aa
userRepository private => App\Model\User #a093
tableName protected => "user" (4)
dbContext private => Nette\Database\Context #94b9 { ... }
authorizator private => App\Authorizator #d393
dump( $this->getUser()->getIdentity() );
:
Nette\Security\Identity #ec7d
id private => 8
roles private => array (1)
0 => "registered" (10)
data private => array (9)
Uživatel opravdu má roli „registered“.
K čemu je slouží guestRole a
authenticatedRole?
- motorcb
- Člen | 552
Authenticator.php:
use Nette;
class Authorizator extends Nette\Object implements Nette\Security\IAuthorizator
{
public function isAllowed( $role, $resource, $privilege )
{
}
}
Authenticator.php
class Authenticator extends Nette\Object implements Nette\Security\IAuthenticator
{
...
public function authenticate( array $credentials )
{
list($email, $password) = $credentials;
$row = $this->userRepository->findByEmail( $email );
if ( !$row )
{
throw new Security\AuthenticationException( 'Neexistující uživatel', self::IDENTITY_NOT_FOUND );
}
if ( $row->password !== $this->calculateHash( $password ) )
{
throw new Security\AuthenticationException( "Špatné heslo", self::INVALID_CREDENTIAL );
}
$roles = array();
$userArray = $row->toArray();
unset( $userArray[ 'password' ] );
$roles = array( "registered" );
return new Security\Identity( $row->id, $roles, $userArray );
}
...
}
- Šaman
- Člen | 2666
GuestRole slouží k označení nepřihlášeného uživatele. I bez
přihlášení máš totiž k dispozici $presenter->getUser()
a
vrací reálnou instanci (nikoliv NULL, jak by si mohl někdo myslet). Onen
nepřihlášený uživatel má roli ‚guest‘ (a s ní můžeš v ACL
normálně pracovat).
AuthenticatedRole bude asi podobná záležitost, ale nikdy jsem ji zatím
nepoužil.
Hoď sem ACL, nebo zkus oprávnění kontrolovat
jednodušeji $presenter->user->isInRole('registered');
- motorcb
- Člen | 552
@vvoody:
$this->getUser()->setAuthorizator( new App\Authorizator() );
$acl = new Nette\Security\Permission;
// definujeme role
$acl->addRole('guest');
$acl->addRole('registered', 'guest'); // registered dědí od guest
$acl->addRole('administrator', 'registered'); // a od něj dědí administrator
//zdroje
$acl->addResource('pool');
// opraveni
$acl->allow('guest', 'pool', 'view');
// registrovaný dědí právo od guesta
$acl->allow('registered', 'pool', 'add');
// administrátor může prohlížet a editovat cokoliv
$acl->allow('administrator', Nette\Security\Permission::ALL, array('view', 'edit', 'add'));
Pokud jsem prihlasen: dump(
$this->getUser()->isInRole(‚registered‘) ); ⇒ FALSE
přitom:
dump( $this->getUser()->getIdentity() );:
Nette\Security\Identity #ba91
id private => 8
roles private => array (1)
0 => "registered" (10)
data private => array (9)
Jsem roli registered mám…
- motorcb
- Člen | 552
@vvoody:
A ACL se pak nic nedělá. To bude asi ten problém :-) Co bych pak měl dělat
s ACL?
Kod je v base presenteru:
public function startup()
{
parent::startup();
$this->getUser()->setAuthorizator( new App\Authorizator() );
$acl = new Nette\Security\Permission;
// definujeme role
$acl->addRole('guest');
$acl->addRole('registered', 'guest'); // registered dědí od guest
$acl->addRole('administrator', 'registered'); // a od něj dědí administrator
//zdroje
$acl->addResource('pool');
// opraveni
$acl->allow('guest', 'pool', 'view');
// registrovaný dědí právo od guesta
$acl->allow('registered', 'pool', 'add');
// administrátor může prohlížet a editovat cokoliv
$acl->allow('administrator', Nette\Security\Permission::ALL, array('view', 'edit', 'add'));
}
- Šaman
- Člen | 2666
Jeden postřeh, který s problémem nesouvisí: Neděď od guesta. Když teď guestovi zakážeš view, tak ho tím zakážeš i registrovanýmu. Já nedědím ani admina, to je jiná kategorie uživatelů, než user. Ber to jako v klasickém OOP. Je registrovaný uživatel speciální případ guesta? Ne – takže nedědit. U admina záleží na interpretaci – podle mě admin není obyč user, protože když uživateli něco zakážeš, admin by na to mít práva stále měl.
A teď k věci: problém bude v tom „Pokud jsem prihlasen: dump(
$this->getUser()->isInRole(‚registered‘) ); ⇒ FALSE“. To je
divné.
Akorát mě nenapadá proč by se to mělo dít. Zkus to na čistém sandboxu
(jakou máš vlastně verzi Nette?) který jsi stáhnul spolu s Nette a jen
uprav přihlašování (nastavení role) a pak zkus jestli to hlásí isInRole
správně. Jestli ano, tak zkus přidat i to acl.
Ještě si zkus dumpnout přímo $this->user->getRoles().
Mimochodem v aktuálním Nette nemusíš psát roli do pole (pokud je jen jedna), ono si to zpracuje samo.
- vvoody
- Člen | 910
motorcb napsal(a):
@vvoody:
A ACL se pak nic nedělá. To bude asi ten problém :-) Co bych pak měl dělat s ACL?
\--
Tak logicky zvyšok objektov o existencii acl netuší keď ho ďalej nepredáš. Tak skús tentokrát niečo zistiť aj sám. Ktorý objekt asi tak to acl potrebuje? Má ten objekt nejakú metódu, ktorou sa mu dá nastaviť? (treba pozrieť api)
- motorcb
- Člen | 552
@Šaman:
Ano, to dědění nedává smysl. Díky za nasměrování. Vycházel jsem z dokumentace: https://doc.nette.org/…thentication
Kam bych měl ukládat to $acl?
Vyzkouším čistý sandbox.
Díky
- Šaman
- Člen | 2666
ACL, resp. Permission je jen implementace rozhraní IAuthorizator, které si aplikace (resp. ten $presenter->user) najde samo. Takže tuto třídu stačí nechat vytvořit v kontejneru (tedy zapsat do configu). Ale s tím, že ti to špatně hlásí isInRole() to nesouvisí, to vůbec nepotřebuje authorizator.
Aha, ty to máš celé z dokumentace.. problém je, že poslední dobou se
mi dokumentace moc nelíbí :/
Ty příklady jsou třeba z pohledu ukázky algoritmu správně, ale nejsou
vhodné k reálnému nasazení i na jednoduchých projektech..
Editoval Šaman (27. 12. 2013 14:14)
- vvoody
- Člen | 910
ffs tak si odpoviem sám
Ktorý objekt asi tak to acl potrebuje?
No samozrejme User!
Má ten objekt nejakú metódu, ktorou sa mu dá nastaviť? (treba pozrieť api)
Samozrejme že má, stačí pozrieť sem https://api.nette.org/…ty/User.html
To že sa Authorizator a Authenticator dá zaregistrovať do DIC ako službu a automaticky sa predá do objektu User je síce pekné, ale dokiaľ si to určitý ľudia nevyskúšajú „ručne“ tak ich reči o DIC a autowiringu budú len miasť a budú si mylne myslieť že ich použitie je nevyhnutné, resp že to je jediné správne/funkčné riešenie ktoré framework ponúka.
- enumag
- Člen | 2118
Poslední dobou tenhle odkaz kopíruju nějak často… https://forum.nette.org/…zace-pouziti#…
Editoval enumag (28. 12. 2013 10:55)