česky | english
NOTA BENE - ROZPRACOVÁNO - Vaše příspěvky a úvahy
Pro Technologii báze znalostí - Pro Technologii báze znalostí - přehled - Pro Technologii báze znalostí - přihlášení certifikátem k webové aplikaci
Řízení projektu dotProject - přihlášení certifikátem
Napsal Markus Warg
Tento dokument pojednává o integraci podpory klientských certifikátů do projektu dotproject verze 2.1.2 (http://www.dotproject.net/).
- Dotproject je balíček, který nabízí funkčnost řízení projektu založenou zcela na webu a open source (otevřeném zdrojovém programu), nahlédněte do dokumentace, pokud Vás téma zajímá. Bohužel to vypadá, že vývoj je právě teď pozastaven, přesto stojí za to do něj nahlédnout.
- Budete potřebovat webový server se zapnutým režimem SSL a účet u CACert pro vytvoření serverového a klientského certifikátu (i když by měl fungovat i s jakýmikoli sebou podepsanými certifikáty).
Teorie
- Protože SSLVerifyClient=optional (nepovinný) je označen v některých dokumentech jako "nemusí fungovat s každým prohlížečem", rozhodl jsem se použít SSLVerifyClient=required (povinný). dotproject používá relace, které docela jasně určují postup: zavést novou přihlašovací stránku, povolit pro ni SSLVerifyclient=required, vytvořit relaci a vrátit se do normálního webového grafického uživatelského rozhraní (GUI).
Tato metoda by měla fungovat pro všechny projekty, které mají přihlašovací stránku a ukládají si do relace stav přihlášení. Nebude to fungovat s Apache BasicAuth.
Konfigurace Apache
- Stačí přidat
- SSLEngine On
- SSLCertificateFile /etc/ssl/private/mykey.pem
- SLCertificateKeyFile /etc/ssl/private/mykey.pem
- SLCACertificateFile /etc/ssl/private/cacert.ca
- k Vaší konfiguraci virtuálního stroje, zaměnit "mykey" názvem souboru s Vaším serverovým certifikátem.
- Dále přidejte příkaz Files k zapnutí SSLVerifyClient:
<Files "certlogin.php">
- SSLVerifyClient required
- SSLVerifyDepth 2
SSLOptions +StdEnvVars
</Files>
- To aktivuje POVINNOU podporu SSLVerifyClient pro jediný soubor (certlogin.php).
Kód
- Potřebujete záplatovat nějaký zdrojový kód a soubory s překladem, abyste oznámili, že html potřebuje klientský certifikát:
Upravte style/*/login.php a přidejte odkaz na certlogin.php k obvyklému přihlašovacímu oknu; pro výchozí styl vložte mezi tlačítko Submit a sekci obnovy ztraceného hesla tento kód:
<tr> <td colspan="2"><a href="certlogin.php=loginCRT=1"><?php echo $AppUI->_('certLogin');?></a></td> </tr>
Nyní přidejte překlad pro "certLogin" do locales/<cc>/common.inc - formát by měl být zcela zřejmý, přidejte jen řádek pro certLogin a zadejte svůj upřednostňovaný text.
- Kopírujte index.php do certlogin.php a aplikujte určité záplaty (patche); viz patch a modifikovaný blok jako celek:
$ diff index.php certlogin.php: 120c120 < if (isset($_REQUEST['login'])) { --- > if (isset($_REQUEST['loginCRT'])) { 122,124c122,124 < $username = dPgetCleanParam( $_POST, 'username', < $password = dPgetCleanParam( $_POST, 'password', < $redirect = dPgetCleanParam( $_REQUEST, 'redirect', --- > $username = dPgetCleanParam( $_SERVER, 'SSL_CLIENT_S_DN_Email', > $signingca = dPgetCleanParam( $_SERVER, 'SSL_CLIENT_I_DN_O', > $redirect = '/'; 128c128 < $ok = $AppUI->login( $username, $password ); --- > $ok = $AppUI->loginCRT( $username, $signingca );
- Záplatovaný blok jako celek:
if (isset($_REQUEST['loginCRT'])) { $username = dPgetCleanParam( $_SERVER, 'SSL_CLIENT_S_DN_Email', $signingca = dPgetCleanParam( $_SERVER, 'SSL_CLIENT_I_DN_O', $redirect = '/'; $AppUI->setUserLocale(); @include_once( DP_BASE_DIR.'/locales/'.$AppUI->user_locale.'/locales.php' ); @include_once DP_BASE_DIR.'/locales/core.php'; $ok = $AppUI->loginCRT( $username, $signingca ); if (!$ok) { $AppUI->setMsg( 'Login Failed'); } else { //Register login in user_acces_log $AppUI->registerLogin(); } addHistory('login', $AppUI->user_id, 'login', $AppUI->user_first_name . ' ' . $AppUI->user_last_name); $AppUI->redirect($redirect); }
- Jak vidíte, je tu zavedena nová funkce: loginCRT, kterou potřebujeme také přidat. Upravte soubor classes/ui.php. Pořiďte si kopii přihlašovací funkce a modifikujte těchto několik řádků kódu:
function loginCRT($username, $signingca) { ... if (@$_REQUEST['loginCRT'] != 1 && @$_POST['login'] != 'login' ... ... if (!$auth->authenticateCRT($username, $signingca)) { return false; } ... }
- Nakonec upravte classes/authenticator.class.php a přidejte novou metodu ke třídě v tomto souboru (předpokládám, že používáte SQLAuthenticator, u jiných metod identifikace se může kód lišit):
class SQLAuthenticator ... function authenticateCRT($username, $signingca) { $userdata = array('markus' => array('crt_email' => 'markus@cacert.org', 'crt_serial' => 'yourserialnumberhere', 'crt_signingca' => 'CAcert Inc.') ); foreach ($userdata as $key => $value) { if ($value['crt_email'] == $username && $value['crt_signingca'] = $signingca) { $this->username = $key; $q = new DBQuery; $q->addTable('users'); $q->addQuery('user_id, user_password'); $q->addWhere("user_username = '$key'"); if (!$rs = $q->exec()) { $q->clear(); return false; } if (!$row = $q->fetchRow()) { $q->clear(); return false; } $this->user_id = $row["user_id"]; $q->clear(); return true; } } return false; }
- Tohle sice na první pohled vypadá docela hloupě, ale funguje to na důkaz správnosti koncepce. Můžete ještě přidat kód k vyhledání crt_email, crt_signca a pořadového čísla v databázi, ale v principu jste výše popsanými kroky skončili.
Příspěvky a úvahy
- YYYYMMDD-Vaše_jméno
Text / Vaše názory, úvahy a výňatky e-mailů, prosím
- YYYYMMDD-Vaše_jméno
Text / Vaše názory, úvahy a výňatky e-mailů, prosím
Kategorie