Navazuji na předchozí návod. Ale navíc jsem řešil, jak co nejjednodušeji zajistit, aby do aplikace mohla jen určitá podmnožina uživatelů z LDAP (u mě konkrétně Active Directory).
Možnosti:
- Využít vlastnosti struktury či atributů Active Directory – u mě nepřipadá v úvahu
- Mít další evidenci v databázi webové aplikace. Například s INDEXem na atribut $username. – Zbytečná evidence navíc, které se musí spravovat.
- Mít ve výčtu povolené $username.
$allow_usernames = array('honza', 'mojmir', 'patrik');
A dále kontrolovat, zda přihlašovaný je v tomto poli. – Evidence navíc a při změně oprávnění je třeba magické úpravy v aplikační logice.
- Přidat kontrolní heslo, které budou znát jen administrátoři. – Zdá se, že je zbytečná další vazba na Active Directory, proč prostě nestačí toto admin heslo, ale pokud vypnu uživatele v Active Directory, tak automaticky zamezím přístup i do administrace, ale bez této kombinace by to nešlo.
Authenticator:
< ?php // pro PHP 5.3 // use Nette\Object, Nette\Security\IAuthenticator, Nette\Security\AuthenticationException, Nette\Security\Identity; class MyAuthenticator extends Object implements IAuthenticator { public function authenticate(array $credentials) { $username = $credentials[self::USERNAME]; $password = $credentials[self::PASSWORD]; $control_password = $credentials['extra']; $ldap_conn = ldap_connect ('ldap://server.domena.cz'); if ($ldap_conn) { $ldapbind = @ldap_bind ($ldap_conn, $username . '@domena.tld', $password); ldap_unbind ($ldap_conn); if ($ldapbind) { if ($control_password === 'nejake_zvolene_kontrolni_heslo') { return new Identity('Správce.', 'Administrátor', $ldapbind); } else { throw new AuthenticationException("Účet nemá dostatečná práva.", self::NOT_APPROVED); } } else { throw new AuthenticationException("Špatné jméno nebo heslo.", self::INVALID_CREDENTIAL); } } else { throw new AuthenticationException("Ověřovací server není dostupný.", self::FAILURE); } } } |
Použití v presenteru (zatím ve stínu starého NETTE):
protected function createComponentLogin() { $form = new AppForm; $form->addText('login', 'Přihlašovací jméno:') ->addRule(Form::FILLED, 'Pole "Přihlašovací jméno" je povinné.'); $form->addPassword('password', 'Heslo:') ->addRule(Form::FILLED, 'Pole "Heslo" je povinné.'); $form->addPassword('control', 'Kontrolní heslo:') ->addRule(Form::FILLED, 'Pole "Kontrolní heslo" je povinné.'); // Obrana proti CSRF $form->addProtection('Vypršel čas pro přihlášení.'); $form->addSubmit('send', ' Přihlásit '); $form->onSubmit[] = array($this, 'formLoginSubmitted'); $this->addComponent($form, "login"); } function formLoginSubmitted($form) { $user = Environment::getUser(); $user->setExpiration('+ 15 minutes'); $values = $form->getValues(); try { // pokusíme se přihlásit uživatele... // tady je to nejdůležitější, třetí parametr LOGINu $user->login($values['login'], $values['password'], $values['control']); // ...a v případě úspěchu přesměrujeme na další stránku $this->flashMessage('Přihlášení proběhlo úspěšně.'); $this->redirect('Admin:default'); } catch (AuthenticationException $e) { $this->flashMessage($e->getMessage(), 'validation'); } } |