Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort des Fachgutachters
Vorwort
1 Einleitung
2 Einführung in eZ Components
3 Die Applikationsbasis
4 Fehlerbehandlung und Debugging
5 Konfiguration
6 Datenbankanbindung
7 ORM mit PersistentObject
8 Template
9 Übersetzung
10 Benutzereingaben validieren
11 Authentifizierung
12 Bildverarbeitung
13 Archive und Dateien
14 Mail
15 Logging
16 Diagramme
17 Feeds und Caching
18 Setup
A Inhalt der Buch-CD
Stichwort
Download: - ZIP, ca. 2,7 MB
Ihre Meinung?
<< zurück | Galileo Computing / <openbook> /eZ Components | vor >>
eZ Components von Tobias Schlitt, Kore Nordmann Das Entwickler-Handbuch
eZ Components geb., mit CD 454 S., 39,90 Euro Galileo Computing ISBN 978-3-8362-1073-7 |
| 11 Authentifizierung
|  | 11.1 Die Authentication-Komponente
|  | 11.2 Einbindung in die Applikation
|  |  | 11.2.1 Eingabeformulare
|  |  | 11.2.2 Formularverarbeitung anpassen
|  |  | 11.2.3 Authentifizierung des Besuchers
|  |  | 11.2.4 Gruppierung von Filtern
|  |  | 11.2.5 OpenID
|  | 11.3 Benutzer in der Datenbank
|  | 11.4 Fazit
## 11.2 Einbindung in die Applikation In der Applikation soll der Besucher der Webseite beim Hinterlassen eines Kommentars zu einem Weblog-Eintrag entweder gegen einen OpenID-Server oder eine passwd-Datei im config/-Verzeichnis authentifiziert werden. Dazu wird zuerst das Kommentarformular um ein optionales Passwortfeld und eine Beschreibung der dem Besucher zur Verfügung stehenden Authentifizierungsmechanismen erweitert. Die Aktion, die den Kommentar abspeichert, muss anschließend Gebrauch von diesen Informationen machen und dafür entsprechend erweitert werden. Die Behandlung der Eingaben, auf denen hier aufgebaut wird, wurde in Kapitel 10, »Benutzereingaben validieren«, beschrieben. ### 11.2.1 Eingabeformulare Wie angesprochen, muss das Formular um ein Passwortfeld erweitert werden. Der betroffene Teil des Templates templates/comment_form.ezt sieht nach der Modifikation wie folgt aus:
    <p>
        {gp_translate( 'To leave a comment you may either authenticate
    		    against the local authentication mechanisms using a password,
    		    or use an OpenID and leave the password blank.', 'comment/new')}
    </p>

    <form name="comment_form" id="comment_form"
        action="{$base}save_comment" method="POST">
        <input type="hidden" name="entryId"
            id="entryId" value="{$entry->id}" />
        <input name="name" id="name" type="text" /><br />
        <input name="password" id="password"
            type="password" /><br />
        <input name="email" id="email" type="text" /><br />
        <textarea name="body" id="body"></textarea><br />
        <input name="save" id="save" type="submit"
            value="{gp_translate('Store entry',
            'comment/new')}" /><br />

    </form>
Listing 11.1 Passwort ins Kommentarformular einfügen Die Aufrufe der Template-Funktionen gp_translate() dienen lediglich der Übersetzung der Texte im Template und sollen hier nicht weiter irritieren. Wesentlich sind der fett markierte Einleitungstext zu Beginn, eingefasst in ein <p>-Element, sowie das neue Input-Feld zur optionalen Eingabe eines Passworts. Der einleitende Text beschreibt dem Besucher des Blogs das Verhalten, das in der Applikation erzielt werden soll. Unter der Angabe eines Passworts wird der Besucher gegen eine Liste lokal gespeicherter Benutzer authentifiziert. Wir werden, um das Beispiel einfach zu halten, lediglich gegen eine passwd-Datei authentifizieren. Andernfalls kann der Besucher das Passwortfeld leer lassen. Der Benutzername wird als OpenID betrachtet und der entsprechende Authentifizierungsmechanismus verwendet. In diesem Fall muss die Webapplikation keine weiteren Daten kennen; der Besucher ist dennoch eindeutig authentifiziert. Falls die Authentifizierung des Besuchers nicht erfolgreich war, erscheint eine entsprechende Fehlermeldung und der Kommentar wird nicht gespeichert. ### 11.2.2 Formularverarbeitung anpassen Die in Kapitel 10, »Benutzereingaben validieren«, entwickelte Verarbeitung der Formulardaten mittels der UserInput-Komponente muss als Nächstes angepasst werden, um das zusätzliche Eingabefeld verarbeiten zu können. Dazu wird zunächst die Methode gpBlogActionComment::getFormDefinition() in der Datei classes/actions/comment.php um das Passwortfeld erweitert:
    'password' => new ezcInputFormDefinitionElement(
        ezcInputFormDefinitionElement::OPTIONAL,
        'string'
    ),
Listing 11.2 Formulardefinition für das Passwort Wie zu erwarten, wird das Passwortfeld als optional deklariert und als Wert wird eine Zeichenkette erwartet. Da das Passwort nicht im Kommentar selbst gespeichert werden soll, muss eine entsprechende Ausnahme in der Methode save() eingebaut werden, die die eigentliche Aktion implementiert und den Kommentar speichert.
    foreach ( $definition as $elementName => $dummy )
    {
        if ( $form->hasValidData( $elementName ) )
        {
            // We do NOT want to store the password
            if ( $elementName !== 'password' )
            {
                $comment->$elementName = $form->$elementName;
            }
        }
        else
        {
            // Error
        }
    }
Listing 11.3 Passwort verarbeiten In der Schleife, die die validen Formulardaten dem Kommentarobjekt zuweist, werden ab jetzt entsprechend nur noch die Formularelemente gespeichert, die nicht das Passwort sind, wie in der sechsten Zeile des Codeausschnitts zu sehen ist. ### 11.2.3 Authentifizierung des Besuchers Nachdem nun die notwendigen Daten in der Applikation verfügbar sind, wird der Authentifizierungsmechanismus vor dem tatsächlichen Speichern des Kommentars eingebaut.
    if ( !empty( $form->password ) )
    {
        // Use local auth mechanisms
        $credentials = new ezcAuthenticationPasswordCredentials(
            $form->name,
            $form->password
        );
        $authentication = new ezcAuthentication( $credentials );

        $authentication->addFilter(
            new ezcAuthenticationHtpasswdFilter(
                dirname( __FILE__ ) . '/../../config/passwd' )
        );
        // Optionally add more filters here

        if ( !$authentication->run() )
        {
            gpBlogController::getInstance()->mainSignals->emit(
                'error',
                'Could not authentificate.'
            );
            return false;
        }
    }
    else
    {
        // OpenID
    }
Listing 11.4 Authentifizierung gegen htaccess Die Authentifizierung besteht bei der Verwendung aller Treiber aus den gleichen Schritten. In der vierten Zeile des Codebeispiels werden zuerst die sogenannte Credentials, die vom Besucher zur Verfügung gestellte Legitimation zum Zugriff, erstellt. Im Falle der Verfügbarkeit von Benutzernamen und Passwort wird ein Objekt der Klasse ezcAuthenticationPasswordCredentials erstellt. Mit der Legitimation wird ein neues Objekt der Klasse ezcAuthentication erzeugt, dem die Filter, die die Treiber zur eigentlichen Authentifizierung implementieren, hinzugefügt werden. In obigem Beispiel wird nur ein Filter der Klasse ezcAuthenticationHtpasswdFilter hinzugefügt, der auf Basis einer vorhandenen passwd-Datei erzeugt wird. Nachdem Sie alle gewünschten Filter hinzugefügt haben, wird die eigentliche Authentifizierung über die Methode run() gestartet, die true liefert, wenn diese erfolgreich war. Im Falle eines Fehlers wird erneut ein Signal mit entsprechender Fehlermeldung gesendet, die dem Besucher das Scheitern zeigt. Falls die Authentifizierung erfolgreich war, wird die Ausführung des aus dem vorigen Kapitel bekannten Codes fortgesetzt, der den Kommentar speichert und zur Seite mit der Erfolgsmeldung weiterleitet. Die passwd-Datei enthält eine einfache Liste von Benutzer-Passwort-Paaren.
    user:passwort
    user2:password
Listing 11.5 Passwörter in der Passwortdatei Wenn sie eine passwd-Datei mit einem der dafür üblichen Programme (wie htpasswd) erstellen, wird normalerweise ein Hashing-Verfahren verwendet, damit das Passwort nicht im Klartext ersichtlich ist. Sie werden sich selbiges natürlich auch bei der Verwendung der Authentication-Komponente wünschen. Dazu können Sie bei der Übergabe des Passworts an das Legitimationsobjekt mit dem gleichen Verfahren verschlüsseln oder hashen, mit dem die Passwörter in der passwd-Datei abgelegt sind. Normalerweise wird dafür entweder crypt() oder ein MD5-Hash verwendet.
Hashing-Verfahren
Das Bilden eines Hash-Werts ist eine linkseindeutige Abbildung einer Zeichenkette auf eine andere Zeichenkette. Das heißt, dass eine Zeichenkette immer den gleichen Hash-Wert hat, aber ein Hash-Wert das Resultat mehrerer Zeichenketten sein kann.
Aufgrund dieser Eigenschaft und der bei den meisten Hashing-Algorithmen klar definierten Länge eignen sich Hash-Werte ausgezeichnet, um Passwörter zu speichern, da das originale Passwort nicht mehr ermittelbar ist.
Hashing-Algorithmen zum Einsatz in der Kryptographie werden mit dem Ziel entwickelt, dass sich zu einem Hash möglichst schwer eine Zeichenkette berechnen lässt, die diesen Hash erzeugt. Durch die gewachsene Größe von Datenbanken sind mittlerweile für MD5 sogenannte Rainbowtables verfügbar, die zu nahezu jedem Hash eine erzeugende Zeichenkette beinhalten. Falls die eigene Benutzerdatenbank kompromittiert wurde, ist es so Angreifern trotz gehashter Passwörter möglich, sich erfolgreich anzumelden. Ein einfacher und effektiver Weg dieses Problem zu vermeiden, ist die Verwendung eines applikationseigenen Seeds bei der Generierung des Hashs.
    $passwordHash = md5( 'my_custom_seed' . $password );
Dies reduziert die Wahrscheinlichkeit, dass der Hash »geknackt« wird, auf die Wahrscheinlichkeit, dass die erzeugende Zeichenkette in der Rainbowtable zufällig mit »my_custom_seed« beginnt.
    // Use local auth mechanisms
    $credentials = new ezcAuthenticationPasswordCredentials(
        $form->name,
        md5( $form->password )
    );
Listing 11.6 Gehashtes Passwort verwenden Mit einer entsprechend angepassten passwd-Datei in config/passwd funktioniert die Authentifizierung auch ohne das Vorliegen der Passwörter im Klartext.
    user:e22a63fb76874c99488435f26b117e37
    user2:5f4dcc3b5aa765d61d8327deb882cf99
Listing 11.7 Passworthashes in Passwortdatei ### 11.2.4 Gruppierung von Filtern Falls mehrere Authentifizierungsmechanismen in einer Applikation verwendet werden sollen, können Sie diese auch kombinieren. Vorstellbar ist, dass ein Besucher sowohl auf LDAP-Servern als auch in der Datenbank der aktuell entwickelten Webapplikation verfügbar sein soll. Das vorige Beispiel wird um eine zweite passwd-Datei mit weiteren Benutzern erweitert.
    $authentication->addFilter(
        new ezcAuthenticationGroupFilter( array(
            new ezcAuthenticationHtpasswdFilter(
                dirname( __FILE__ ) . '/../../config/passwd' ),
            new ezcAuthenticationHtpasswdFilter(
                dirname( __FILE__ ) . '/../../config/users.passwd' )
        ) )
    );
Listing 11.8 Filtergruppen verwenden Wenn Sie mehrere Filter kombinieren, erstellen Sie einen ezcAuthenticationGroupFilter mit einem Array der zu kombinierenden Filter. In der Standardeinstellung muss nur einer der enthaltenen Filter die Besucherlegitimation validieren, damit der Gruppen-Filter validiert, sodass in diesem Beispiel der Besucher entweder in der Datei config/users.passwd oder in config/passwd gelistet sein muss. Wenn eine Legitimation gegen alle Filter einer Gruppe validieren soll, kann dies über eine Option im Filter eingestellt werden. Über die Verschachtelung von Gruppen-Filtern lassen sich so auch komplexe Authentifizierungslogiken abbilden. ### 11.2.5 OpenID Um OpenID in die Applikation zu integrieren, muss mehr beachtet werden als bei der einfach Authentifizierung gegen eine passwd-Datei. Bei der Authentifizierung gegen OpenID übergibt der Besucher eine ID, die dem Schema einer URL entspricht, so zum Beispiel http://xlogon.net/koredn für einen der Autoren dieses Buches, der sich für eine OpenID bei dem deutschen Service http://xlogon.net registriert hat. Um die Authentizität des Besuchers sicherzustellen, leitet die Applikation an den OpenID-Service-Provider weiter, der den Besucher dann bittet, sich einzuloggen, also sich bei dem OpenID-Service-Provider selbst zu authentifizieren, und dann zu bestätigen, dass es der anfragenden Webseite erlaubt ist, diesen OpenID-Account zu verwenden. Dies sieht bei http://xlogon.net wie folgt aus. Nach der Bestätigung des Zugriffs auf die Daten beim OpenID-Service-Provider wird dieser wieder zurück an die Webapplikation weiterleiten, mit der verschlüsselten Bestätigung der Verifizierung der Authentifizierung als GET-Parameter. Durch die Verwendung von ausreichend sicheren kryptographischen Methoden ist eine Vortäuschung der Authentifizierung nahezu ausgeschlossen. Hier klicken, um das Bild zu vergrößern Abbildung 11.1 Bestätigung beim OpenID-Provider Die Webapplikation selbst muss auf die GET-Parameter reagieren und kann den Vorgang, der durch den Authentifizierungsprozess unterbrochen wurde, abschließend fortsetzen. Entsprechend erweitern wir nun den Quellcode zur Authentifizierung gegen OpenID:
    session_start();

    if ( count( $_POST ) )
    {
        $_SESSION['comment'] = $comment;
        $_SESSION['openid'] = $form->name;
    }

    // Use OpenID authentication
    $credentials = new ezcAuthenticationIdCredentials(
        $_SESSION['openid']
    );
    $authentication = new ezcAuthentication( $credentials );

    $authentication->addFilter(
        new ezcAuthenticationOpenidFilter()
    );

    if ( !$authentication->run() )
    {
        return gpBlogController::getInstance()->mainSignals->emit(
            'error',
            'Could not authentificate.'
        );
    }

    $comment = $_SESSION['comment'];
Listing 11.9 Authentifizierung gegen OpenID Weil der Prozess durch Weiterleitungen an den OpenID-Service-Provider unterbrochen wird, müssen Sie das Kommentarobjekt in der Variablen $comment in der Session speichern, um es später wieder zum Speichern zur Verfügung zu haben. Da das Blog bislang keine Sessions verwendet und die Rückleitung wieder in dieser Methode enden wird, ist es für uns ausreichend, die Session nur in dieser Methode zu etablieren. Für die Authentifizierung gegen OpenID können sie keine Passwort-Legitimation verwenden, da OpenID ja lediglich eine ID verwendet und das Passwort nur beim OpenID-Service-Provider eingegeben werden muss. Aus diesem Grund wird ein Objekt der Klasse ezcAuthenticationIdCredentials erstellt und dem Konstruktor von ezcAuthentication übergeben. Der einzige in diesem Codebeispiel verwendete Filter der Klasse ezcAuthenticationOpenidFilter wird hinzugefügt und die Authentifizierung wie gewohnt über die Methode run() gestartet. Im Gegensatz zum vorigen Beispiel wird von der Authentication-Komponente nun ein Location-Header zur Weiterleitung zum OpenID-Service-Provider gesendet und die Ausführung der Applikation abgebrochen. Dort muss sich der Besucher nun, falls er es nicht schon vorher getan hat, authentifizieren. Hier klicken, um das Bild zu vergrößern Abbildung 11.2 Notwendige Authentifizierung beim OpenID-Service-Provider Je nach OpenID-Service-Provider können Sie einer Webseite auch die Verwendung der eigenen ID generell erlauben, sodass nicht bei jedem erneuten Log-in nachgefragt wird, ob Sie diesen Log-in erlauben. Sollten Sie dann bereits beim OpenID-Service-Provider authentifiziert sind, finden zwar auch Weiterleitungen im Hintergrund statt, aber Sie bekommen von dem OpenID-Service-Provider nichts mehr zu sehen, sondern werden direkt authentifiziert. Andernfalls wird eine Bestätigungsanfrage, wie auf dem obigen Screenshot zu sehen, angezeigt. Wie zuvor bereits angesprochen, werden die Parameter, die die Validierung der Legitimation bestätigen, per GET übertragen. Die originalen POST-Parameter sind in der Anfrage selbstverständlich nicht mehr enthalten, entsprechend muss die Methode diesbezüglich leicht angepasst werden, sodass die Fomularverarbeitung sowie der Versuch der Authentifizierung gegen die passwd-Dateien nur noch bei Existenz der POST-Parameter stattfinden.
    if ( count( $_POST ) )
    {
        // Do the form stuff only, when a post request was sent, and
        // not, when we might have an OpenID response
    }

    // Authentificate user
    if ( count( $_POST ) && !empty( $form->password ) )
    {
        // Authetificate against passwd
    }
    else
    {
        // Known OpenID stuff
    }
Listing 11.10 Veränderte Logik zur Verarbeitung der GET-Parameter Nach diesen strukturellen Modifikationen ist es dem Besucher nun möglich, sich sowohl per Passwort gegen die passwd-Dateien zu authentifizieren als dies auch über einen OpenID-Service-Provider seiner Wahl zu tun, ohne dass dem Besitzer des Blogs ein Passwort oder der Hash-Wert eines Passworts bekannt sein muss. ### Ihr Kommentar Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
<< zurück | <top> | vor >>
Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen? Ihre Meinung
Buchempfehlungen
| PHP 5.3 und MySQL 5.1
| Besser PHP programmieren
| Webshops mit Magento
| Sichere Webanwendungen
| PHP 5.3 und MySQL 5.1 - Videotraining
| Apache 2
| Suchmaschinen- Optimierung für Webentwickler
| Joomla! 1.5
Shopping
Versandkostenfrei bestellen in Deutschland und Österreich Info

Copyright © Galileo Press 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

[Galileo Computing]
Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de