| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 15157 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.openid.consumer">
- <title>Zend_OpenId_Consumer Grundlagen</title>
- <para>
- <classname>Zend_OpenId_Consumer</classname> kann verwendet werdeb um OpenID Authentifizierung auf Webseiten
- zu implementieren.
- </para>
- <sect2 id="zend.openid.consumer.authentication">
- <title>OpenID Authentifikation</title>
- <para>
- Aus der Sicht eines Website Entwicklers, geschieht die Authentifikation von OpenID in drei Schritten:
- </para>
- <orderedlist>
- <listitem>
- <para>
- Zeige das OpenID Authentifikations Formular
- </para>
- </listitem>
- <listitem>
- <para>
- Akzeptiere die OpenID Identität und übergib Sie an den OpenID Provider
- </para>
- </listitem>
- <listitem>
- <para>
- Überprüfe die Antwort des OpenID Providers
- </para>
- </listitem>
- </orderedlist>
- <para>
- Das OpenID Authentifikations Protokoll benötigt aktuell mehrere, aber viele von Ihnen sind
- innerhalb von <classname>Zend_OpenId_Consumer</classname> gekapselt, und deshalb für den Entwickler transparent.
- </para>
- <para>
- Der End-Benutzer initiiert den OpenID Authentifikations Prozess indem er Seine oder Ihre
- Identifikations Daten in der entsprechenden Form übermittelt. Das folgende Beispiel zeigt ein
- einfaches Formular das einen OpenID Identifikator akzeptiert. Es gilt zu beachten das das Beispiel
- nur einen Login demonstriert.
- </para>
- <example id="zend.openid.consumer.example-1">
- <title>Das einfache OpenID Login Formular</title>
- <programlisting role="php"><![CDATA[
- <html><body>
- <form method="post" action="example-1_2.php"><fieldset>
- <legend>OpenID Login</legend>
- <input type="text" name="openid_identifier">
- <input type="submit" name="openid_action" value="login">
- </fieldset></form></body></html>
- ]]></programlisting>
- </example>
- <para>
- Dieses Formular übergibt bei der Übertragung eine OpenID Identität an das folgende PHP Skript welches
- den zweiten Schritt der Authentifizierung durchführt. Das PHP Skript muss in diesem Schritt nur die
- <classname>Zend_OpenId_Consumer::login()</classname> Methode aufrufen. Das erste Argument dieser Methode
- akzeptiert eine OpenID Identität, und das zweite ist die URL des Skripts das den dritten und letzten
- Schritt der Authentifizierung behandelt.
- </para>
- <example id="zend.openid.consumer.example-1_2">
- <title>Der Authentifizierungs Anfrage Handler</title>
- <programlisting role="php"><![CDATA[
- $consumer = new Zend_OpenId_Consumer();
- if (!$consumer->login($_POST['openid_identifier'], 'example-1_3.php')) {
- die("OpenID Login fehlgeschlagen.");
- }
- ]]></programlisting>
- </example>
- <para>
- Die <classname>Zend_OpenId_Consumer::login()</classname> Methode führt eine Suche nach einem gegebenen Identifikator
- durch und findet, bei Erfolg, die Adresse des Identitäts Providers und dessen Lokalen Idenzifizierer
- durch. Dann erstellt es eine Assoziation zum gegebenen Provider sodas beide, die Site und der
- Provider, um das gleiche Geheimnis teilen das verwendet wird um nachfolgende Nachrichten zu
- verschlüsseln. Letztendlich wird eine Authentifikations Anfrage an den Provider übergeben. Diese
- Anfrage leitet den Web-Browser des End-Benutzers zu einer OpenID Server Site um, wo der
- Benutzer die Möglichkeit habt den Authentifizierungs Prozess fortzuführen.
- </para>
- <para>
- Ein OpenID Provider fragt nochmalerweise Benutzer nach Ihrem Passwort (wenn Sie vorher noch nicht
- angemeldet waren), wenn der Benutzer dieser Site vertraut und welche Informationen zu der Site
- zurückgegeben werden können. Diese Interaktionen sind für den OpenID Konsument nicht sichtbar
- sodas es für Ihn keine Möglichkeit gibt das Benutzerpasswort oder andere Informationen zu
- bekommen bei denen der Benutzer nicht gesagt hat das der OpenId Provider Sie teilen darf.
- </para>
- <para>
- Bei Erfolg wird <classname>Zend_OpenId_Consumer::login()</classname> nicht zurückkommen, sondern eine HTTP
- Umleitung durchführt. Trotzdem wird im Falle eine Fehler ein false zurückgeben wird. Fehler können
- durch eine ungültige Identität, einen Provider der nicht antwortet, Kommunikations Fehler, usw.
- auftreten.
- </para>
- <para>
- Der dritte Schritt der Authentifikation wird durch die Antwort vom OpenID Provider initiiert,
- nachdem dieser das Benutzerpasswort authentifiziert hat. Diese Antwort wird indirekt, als HTTP
- Umleitung übergeben, indem der Webbrowsers des End-Benutzers verwendet wird. Der Konsument muß nun
- einfach prüfen ob die Antwort gültig ist.
- </para>
- <example id="zend.openid.consumer.example-1_3">
- <title>Der Authentifizierungs Antwort Prüfer</title>
- <programlisting role="php"><![CDATA[
- $consumer = new Zend_OpenId_Consumer();
- if ($consumer->verify($_GET, $id)) {
- echo "GÜLTIG ". htmlspecialchars($id);
- } else {
- echo "UNGÜLTIG" . htmlspecialchars($id);
- }
- ]]></programlisting>
- </example>
- <para>
- Diese Prüfung wird durchgeführt indem die <classname>Zend_OpenId_Consumer::verify</classname> Methode
- verwendet wird, welche ein ganzes Array von HTTP Anfrage Argumenten entgegennimmt und prüft ob
- diese Antwort durch den OpenID Provider richtig signiert wurde. Sie kann die erhaltete OpenID
- Identität, die vom Endbenutzer im ersten Schritt angegeben wurde, zuordnen, indem ein zweites,
- optionales, Argument eingegeben wird.
- </para>
- </sect2>
- <sect2 id="zend.openid.consumer.combine">
- <title>Alle Schritte in einer Seite kombinieren</title>
- <para>
- Das folgende Beispiel kombiniert alle drei Schritte in einem Skript. Es bietet keine neuen
- Funktionalitäten. Der Vorteil der Verwendung eines einzelnen Skripts ist, das Entwickler keine
- URLs für das Skript definieren muss, das den nächsten Schritt durchführt. Standardmäßig verwenden
- alle Schritte die gleiche URL. Trotzdem enthält das Skript nun etwas Dispatchcode um den korrekten
- Code für jeden Schritt der Authentifikation aufzurufen.
- </para>
- <example id="zend.openid.consumer.example-2">
- <title>Das komplette Skript für ein OpenID Login</title>
- <programlisting role="php"><![CDATA[
- $status = "";
- if (isset($_POST['openid_action']) &&
- $_POST['openid_action'] == "login" &&
- !empty($_POST['openid_identifier'])) {
- $consumer = new Zend_OpenId_Consumer();
- if (!$consumer->login($_POST['openid_identifier'])) {
- $status = "OpenID Login fehlgeschlagen.";
- }
- } else if (isset($_GET['openid_mode'])) {
- if ($_GET['openid_mode'] == "id_res") {
- $consumer = new Zend_OpenId_Consumer();
- if ($consumer->verify($_GET, $id)) {
- $status = "GÜLTIG " . htmlspecialchars($id);
- } else {
- $status = "UNGÜLTIG " . htmlspecialchars($id);
- }
- } else if ($_GET['openid_mode'] == "cancel") {
- $status = "ABGEBROCHEN";
- }
- }
- ?>
- <html><body>
- <?php echo "$status<br>" ?>
- <form method="post">
- <fieldset>
- <legend>OpenID Login</legend>
- <input type="text" name="openid_identifier" value=""/>
- <input type="submit" name="openid_action" value="login"/>
- </fieldset>
- </form>
- </body></html>
- ]]></programlisting>
- </example>
- <para>
- Zusätzlich unterscheidet dieser Code zwischen abgebrochen und ungültigen Authentifizierungs Antworten.
- Der Provider gibt eine abgebrochene Antwort zurück, wenn der Identitäts Provider die gegebene
- Identität nicht unterstützt, der Benutzer nicht angemeldet ist, oder der Benutzer der Seite
- nicht vertraut. Eine ungültige Antwort zeigt an das die Antwort dem OpenId Protokoll nicht
- entspricht oder nicht korrekt signiert wurde.
- </para>
- </sect2>
- <sect2 id="zend.openid.consumer.realm">
- <title>Konsumenten Bereiche</title>
- <para>
- Wenn eine OpenID-aktivierte Site eine Authentifikations Anfrage an einen Provider übergibt,
- identifiziert diese sich selbst mit einer Bereichs URL. Diese URL kann als Root der vertrauten
- Site betrachtet werden. Wenn der Benutzer der Bereichs URL vertraut, dann sollte er oder Sie das
- auch bei der passenden und den untergeordneten URLs tun.
- </para>
- <para>
- Standardmäßig wird der Bereich automatisch auf die URL des Verzeichnisses gesetzt indem das Login
- Skript ist. Dieser Standardwert ist für die meisten, aber nicht alle, Fälle ausreichend. Manchmal
- sollte einer komplette Domain, und nicht einem Verzeichnis vertraut werden. Oder sogar einer
- Kombination von verschiedenen Servern in einer Domain.
- </para>
- <para>
- Um den Standardwert zu überschreiben müssen Entwickler die Bereichs URL als drittes Argument an die
- <classname>Zend_OpenId_Consumer::login</classname> Methode übergeben. Im folgenden Beispiel fragt eine einzelne
- Interaktion nach vertrauten Zugriff auf alle php.net Sites.
- </para>
- <example id="zend.openid.consumer.example-3_2">
- <title>Authentifizierungs Anfrage für spezielle Bereiche</title>
- <programlisting role="php"><![CDATA[
- $consumer = new Zend_OpenId_Consumer();
- if (!$consumer->login($_POST['openid_identifier'],
- 'example-3_3.php',
- 'http://*.php.net/')) {
- die("OpenID Login fehlgeschlagen.");
- }
- ]]></programlisting>
- </example>
- <para>
- Dieses Beispiel implementiert nur den zweiten Schritt der Authentifikation; der erste und dritte
- Schritt sind die identisch mit dem ersten Beispiel.
- </para>
- </sect2>
- <sect2 id="zend.openid.consumer.check">
- <title>Sofortige Prüfung</title>
- <para>
- In einigen Fällen muß eine Anwendung nur prüfen ob ein Benutzer bereits auf einem vertrauten
- OpenID Server eingeloggt ist ohne einer Interaktion mit dem Benutzer. Die
- <classname>Zend_OpenId_Consumer::check</classname> Methode führt genau das durch. Sie wird mit den
- gleichen Argumenten wie <classname>Zend_OpenId_Consumer::login</classname> ausgeführt, aber Sie zeigt dem
- Benutzer keine OpenID Serverseiten. Aus Sicht des Benutzers ist dieser Prozess transparent, und es
- scheint als ob er die Site nie verlässt. Der dritte Schritt ist erfolgreich wenn der
- Benutzer bereits angemeldet ist und der Site vertraut, andernfalls ist er erfolglos.
- </para>
- <example id="zend.openid.consumer.example-4">
- <title>Sofortige Prüfung ohne Interaktion</title>
- <programlisting role="php"><![CDATA[
- $consumer = new Zend_OpenId_Consumer();
- if (!$consumer->check($_POST['openid_identifier'], 'example-4_3.php')) {
- die("OpenID Login fehlgeschlaten.");
- }
- ]]></programlisting>
- </example>
- <para>
- Das Beispiel implementiert nur den zweiten Schritt der Authentifikation; der erste und dritte
- Schritt sind dem obigen Beispiel ähnlich.
- </para>
- </sect2>
- <sect2 id="zend.openid.consumer.storage">
- <title>Zend_OpenId_Consumer_Storage</title>
- <para>
- Es gibt drei Schritte beim Authentifizierungs Prozess von OpenID, und jeder wird durch eine
- separate HTTP Anfrage durchgeführt. Um die Informationen zwischen den Anfragen zu speichern
- verwendet <classname>Zend_OpenId_Consumer</classname> einen internen Speicher.
- </para>
- <para>
- Entwickler müssen sich nicht notwendigerweise um die Speicherung kümmern weil
- <classname>Zend_OpenId_Consumer</classname> standardmäßig einen dateibasierten Speicher im temporären
- Verzeichnis verwendet, ähnlich wie PHP Sessions. Trotzdem ist dieser Speicher nicht in allen
- Situationen richtig. Einige Entwickler wollen Informationen in einer Datenbank speichern, wärend
- andere einen üblichen Speicher für große Server-Farmen verwenden wollen. Glücklicherweise können
- Entwickler den Standardspeicher sehr einfach mit Ihrem eigenen tauschen. Um einen eigenen
- Speichermechanismus zu spezifizieren muß nur die <classname>Zend_OpenId_Consumer_Storage</classname>
- Klasse erweitert werden und diese Unterklasse dem <classname>Zend_OpenId_Consumer</classname> Konstruktor
- im ersten Argument übergeben werden.
- </para>
- <para>
- Das folgende Beispiel demonstriert einen einfachen Speicher Mechanismus der <classname>Zend_Db</classname>
- als sein Backend verwendet und drei Gruppen von Funktionen bereitstellt. Der erste Gruppe enthält
- Funktionen für die Arbeit mit Assoziationen, wärend die zweite Gruppe erkannte Informationen cacht,
- und die dritte Gruppe kann verwendet werden um zu prüfen ob die Antwort eindeutig ist. Die Klasse
- kann einfach mit bestehenden oder neuen Datenbanken verwendet werden; wenn die benötigten Tabellen
- nicht existieren, wird er Sie erstellen.
- </para>
- <example id="zend.openid.consumer.example-5">
- <title>Datenbank Speicher</title>
- <programlisting role="php"><![CDATA[
- class DbStorage extends Zend_OpenId_Consumer_Storage
- {
- private $_db;
- private $_association_table;
- private $_discovery_table;
- private $_nonce_table;
- // Übergib das Zend_Db_Adapter Objekt und die Namen der
- // benötigten Tabellen
- public function __construct($db,
- $association_table = "association",
- $discovery_table = "discovery",
- $nonce_table = "nonce")
- {
- $this->_db = $db;
- $this->_association_table = $association_table;
- $this->_discovery_table = $discovery_table;
- $this->_nonce_table = $nonce_table;
- $tables = $this->_db->listTables();
- // Erstelle die Assoziationstabellen wenn Sie nicht existieren
- if (!in_array($association_table, $tables)) {
- $this->_db->getConnection()->exec(
- "create table $association_table (" .
- " url varchar(256) not null primary key," .
- " handle varchar(256) not null," .
- " macFunc char(16) not null," .
- " secret varchar(256) not null," .
- " expires timestamp" .
- ")");
- }
- // Erstelle die Discoverytabellen wenn Sie nicht existieren
- if (!in_array($discovery_table, $tables)) {
- $this->_db->getConnection()->exec(
- "create table $discovery_table (" .
- " id varchar(256) not null primary key," .
- " realId varchar(256) not null," .
- " server varchar(256) not null," .
- " version float," .
- " expires timestamp" .
- ")");
- }
- // Erstelle die Nouncetabellen wenn Sie nicht existieren
- if (!in_array($nonce_table, $tables)) {
- $this->_db->getConnection()->exec(
- "create table $nonce_table (" .
- " nonce varchar(256) not null primary key," .
- " created timestamp default current_timestamp" .
- ")");
- }
- }
- public function addAssociation($url,
- $handle,
- $macFunc,
- $secret,
- $expires)
- {
- $table = $this->_association_table;
- $secret = base64_encode($secret);
- $this->_db
- ->query('insert into ' .
- $table . " (url, handle, macFunc, secret, expires) " .
- "values ('$url', '$handle', '$macFunc', " .
- "'$secret', $expires)");
- return true;
- }
- public function getAssociation($url,
- &$handle,
- &$macFunc,
- &$secret,
- &$expires)
- {
- $table = $this->_association_table;
- $this->_db->query("delete from $table where expires < " . time());
- $res = $this->_db->fetchRow('select handle, macFunc, secret, expires ' .
- "from $table where url = '$url'");
- if (is_array($res)) {
- $handle = $res['handle'];
- $macFunc = $res['macFunc'];
- $secret = base64_decode($res['secret']);
- $expires = $res['expires'];
- return true;
- }
- return false;
- }
- public function getAssociationByHandle($handle,
- &$url,
- &$macFunc,
- &$secret,
- &$expires)
- {
- $table = $this->_association_table;
- $this->_db->query("delete from $table where expires < " . time());
- $res = $this->_db
- ->fetchRow('select url, macFunc, secret, expires ' .
- "from $table where handle = '$handle'");
- if (is_array($res)) {
- $url = $res['url'];
- $macFunc = $res['macFunc'];
- $secret = base64_decode($res['secret']);
- $expires = $res['expires'];
- return true;
- }
- return false;
- }
- public function delAssociation($url)
- {
- $table = $this->_association_table;
- $this->_db->query("delete from $table where url = '$url'");
- return true;
- }
- public function addDiscoveryInfo($id,
- $realId,
- $server,
- $version,
- $expires)
- {
- $table = $this->_discovery_table;
- $this->_db
- ->query("insert into $table " .
- "(id, realId, server, version, expires) " .
- "values (" .
- "'$id', '$realId', '$server', $version, $expires)");
- return true;
- }
- public function getDiscoveryInfo($id,
- &$realId,
- &$server,
- &$version,
- &$expires)
- {
- $table = $this->_discovery_table;
- $this->_db->query("delete from $table where expires < " . time());
- $res = $this->_db
- ->fetchRow('select realId, server, version, expires ' .
- "from $table where id = '$id'");
- if (is_array($res)) {
- $realId = $res['realId'];
- $server = $res['server'];
- $version = $res['version'];
- $expires = $res['expires'];
- return true;
- }
- return false;
- }
- public function delDiscoveryInfo($id)
- {
- $table = $this->_discovery_table;
- $this->_db->query("delete from $table where id = '$id'");
- return true;
- }
- public function isUniqueNonce($nonce)
- {
- $table = $this->_nonce_table;
- try {
- $ret = $this->_db
- ->query("insert into $table (nonce) values ('$nonce')");
- } catch (Zend_Db_Statement_Exception $e) {
- return false;
- }
- return true;
- }
- public function purgeNonces($date=null)
- {
- }
- }
- $db = Zend_Db::factory('Pdo_Sqlite',
- array('dbname'=>'/tmp/openid_consumer.db'));
- $storage = new DbStorage($db);
- $consumer = new Zend_OpenId_Consumer($storage);
- ]]></programlisting>
- </example>
- <para>
- Dieses Beispiel zeigt keinen OpenID Authentifikations Code, aber dieser Code würde der gleiche sein
- wie der für die anderen Beispiel in diesem Kapitel.
- </para>
- </sect2>
- <sect2 id="zend.openid.consumer.sreg">
- <title>Einfache Registrations Erweiterung</title>
- <para>
- Zusätzlich zur Authentifikation kann OpenID Standard für einen leichtgewichtigen Profiltausch
- verwendet werden, um Informationen über einen Benutzer über mehrere Sites hinweg portabel zu machen.
- Dieses Feature wird nicht durch die OpenID Authentifikations Spezifikation abgedeckt, aber vom
- OpenID Einfachen Registrierungs Erweiterungs Protokoll unterstützt. Dieses Protokoll erlaubt es
- OpenID-aktivierten Sites nach Informationen über End-Benutzern von OpenID Providers zu fragen.
- Diese Informationen können folgendes beinhalten:
- </para>
- <itemizedlist>
- <listitem>
- <para>
- <emphasis>nickname</emphasis>
- - ein UTF-8 String den der End-Benutzer als Spitzname verwendet.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>email</emphasis>
- - die Email Adresse des Benutzers wie in Sektion 3.4.1 von RFC2822 spezifiziert.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>fullname</emphasis>
- - eine UTF-8 String Repräsentation des kompletten Namens des Benutzers.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>dob</emphasis>
- - das Geburtsdatum des Benutzers im Format 'YYYY-MM-DD'. Jeder Wert dessen Repräsentation
- weniger als die speifizierte Anzahl an Ziffern in diesem Format verwendet sollte mit Nullen
- aufgefüllt werden. In anderen Worten, die Länge dieses Wertes muß immer 10 sein. Wenn der
- Benutzer irgendeinen Teil dieses Wertes (z.B. Jahr, Monat oder Tag) nicht angeben will,
- dann muß dieser auf Null gesetzt werden. Wenn ein Benutzer zum Beispiel angeben will das
- sein Geburtsdatum in das Jahr 1980 fällt, aber nicht den Monat oder Tag angeben will, dann
- sollte der zurückgegebene Wert '1980-00-00' sein.
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>gender</emphasis>
- - das Geschlecht des Benutzers: "M" für männlich, "F" für weiblich
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>postcode</emphasis>
- - ein UTF-8 String der dem Postleitzahl System des Landes des End-Benutzers entspricht
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>country</emphasis>
- - das Land des Wohnsitzes des Benutzers wie spezifiziert in ISO3166
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>language</emphasis>
- - die bevorzugte Sprache des Benutzers wie spezifiziert in ISO639
- </para>
- </listitem>
- <listitem>
- <para>
- <emphasis>timezone</emphasis>
- - ein ASCII String von der Zeitzonen Datenbank. Zum Beispiel, "Europe/Paris" oder
- "America/Los_Angeles".
- </para>
- </listitem>
- </itemizedlist>
- <para>
- Eine OpenID-aktivierte Web-Seite kann nach jeder beliebigen Kombination dieser Felder fragen.
- Sie kann auch einige Informationen strikt fordern und es Benutzern erlauben zusätzliche Informationen
- anzubieten oder zu verstecken. Das folgende Beispiel Instanziiert die
- <classname>Zend_OpenId_Extension_Sreg</classname> Klasse die einen <emphasis>nickname</emphasis>
- (Spitzname) benötigt und optional eine <emphasis>email</emphasis> (E-Mail) und einen
- <emphasis>fullname</emphasis> (vollständigen Namen) benötigt.
- </para>
- <example id="zend.openid.consumer.example-6_2">
- <title>Anfragen mit einer einfachen Registrations Erweiterung senden</title>
- <programlisting role="php"><![CDATA[
- $sreg = new Zend_OpenId_Extension_Sreg(array(
- 'nickname'=>true,
- 'email'=>false,
- 'fullname'=>false), null, 1.1);
- $consumer = new Zend_OpenId_Consumer();
- if (!$consumer->login($_POST['openid_identifier'],
- 'example-6_3.php',
- null,
- $sreg)) {
- die("OpenID Login fehlgeschlagen.");
- }
- ]]></programlisting>
- </example>
- <para>
- Wie man sieht akzeptiert der <classname>Zend_OpenId_Extension_Sreg</classname> Konstruktor ein Array von
- OpenId Feldern. Das Array hat den Namen der Felder als Indezes zu einem Flag das anzeigt ob das
- Feld benötigt wird oder nicht. <emphasis>true</emphasis> bedeutet der Wert wird benötigt und
- <emphasis>false</emphasis> bedeutet das Feld ist optional. Die Methode
- <classname>Zend_OpenId_Consumer::login</classname> akzeptiert eine Erweiterung oder ein Array von
- Erweiterungen als sein viertes Argument.
- </para>
- <para>
- Im dritten Schritt der Authentifikation sollte das <classname>Zend_OpenId_Extension_Sreg</classname> Objekt
- an <classname>Zend_OpenId_Consumer::verify</classname> übergeben werden. Anschließend wird die Methode
- <classname>Zend_OpenId_Extension_Sreg::getProperties</classname>, bei erfolgreicher Authentifizierung,
- ein assoziatives Array von benötigten Feldern zurückgeben.
- </para>
- <example id="zend.openid.consumer.example-6_3">
- <title>Antworten mit einer einfachen Registierungs Erweiterung prüfen</title>
- <programlisting role="php"><![CDATA[
- $sreg = new Zend_OpenId_Extension_Sreg(array(
- 'nickname'=>true,
- 'email'=>false,
- 'fullname'=>false), null, 1.1);
- $consumer = new Zend_OpenId_Consumer();
- if ($consumer->verify($_GET, $id, $sreg)) {
- echo "GÜLTIG " . htmlspecialchars($id) . "<br>\n";
- $data = $sreg->getProperties();
- if (isset($data['nickname'])) {
- echo "Spitzname: " . htmlspecialchars($data['nickname']) . "<br>\n";
- }
- if (isset($data['email'])) {
- echo "Email: " . htmlspecialchars($data['email']) . "<br>\n";
- }
- if (isset($data['fullname'])) {
- echo "Vollständiger Name: " . htmlspecialchars($data['fullname'])
- . "<br>\n";
- }
- } else {
- echo "UNGÜLTIG " . htmlspecialchars($id);
- }
- ]]></programlisting>
- </example>
- <para>
- Wenn das <classname>Zend_OpenId_Extension_Sreg</classname> Objekt ohne Argumente erstellt wurde, sollte der
- Benutzercode selbst das Vorhandensein der benötigten Daten prüfen. Trotzdem, wenn das Objekt mit
- der gleichen Liste an benötigten Feldern wie im zweiten Schritt erstellt wird, wird es automatisch
- die Existenz der benötigten Daten prüfen. In diesem Fall wird <classname>Zend_OpenId_Consumer::verify</classname>
- <emphasis>false</emphasis> zurückgeben wenn irgendeines der benötigten Felder fehlt.
- </para>
- <para>
- <classname>Zend_OpenId_Extension_Sreg</classname> verwendet standardmäßig die Version 1.0 weil die
- Spezifikation der Version 1.1 noch nicht fertiggestellt wurde. Trotzdem unterstützen einige
- Bibliotheken die Version 1.0 nicht vollständig. Zum Beispiel benötigt www.myopenid.com einen
- SREG Namensraum in den Anfragen der nur in 1.1 vorhanden ist. Um mit so einem Server zu Arbeiten
- muß man die Version 1.1 explizit im <classname>Zend_OpenId_Extension_Sreg</classname> Konstruktor setzen.
- </para>
- <para>
- Das zweite Argument des <classname>Zend_OpenId_Extension_Sreg</classname> Konstruktors ist eine Policy URL,
- die dem Benutzer durch den Identitäts Provider zur Verfügung gestellt werden sollte.
- </para>
- </sect2>
- <sect2 id="zend.openid.consumer.auth">
- <title>Integration mit Zend_Auth</title>
- <para>
- Zend Framework bietet eine spezielle Klasse für die Unterstützung von Benutzer Authentifikation:
- <classname>Zend_Auth</classname>. Diese Klasse kann zusammen mit <classname>Zend_OpenId_Consumer</classname> verwendet
- werden. Das folgende Beispiel zeigt wie <code>OpenIdAdapter</code> das
- <classname>Zend_Auth_Adapter_Interface</classname> mit der <code>authenticate</code> Methode implementiert.
- Diese führt eine Authentifikations Anfrage und Verifikation durch.
- </para>
- <para>
- Der große Unterschied zwischen diesem Adapter und dem bestehenden ist, das er mit zwei HTTP
- Anfragen arbeitet und einen Dispatch code enthält um den zweiten oder dritten Schritt der
- OpenID Authentifikation durchzuführen.
- </para>
- <example id="zend.openid.consumer.example-7">
- <title>Zend_Auth Adapter für OpenID</title>
- <programlisting role="php"><![CDATA[
- class OpenIdAdapter implements Zend_Auth_Adapter_Interface {
- private $_id = null;
- public function __construct($id = null) {
- $this->_id = $id;
- }
- public function authenticate() {
- $id = $this->_id;
- if (!empty($id)) {
- $consumer = new Zend_OpenId_Consumer();
- if (!$consumer->login($id)) {
- $ret = false;
- $msg = "Authentifizierung fehlgeschlagen.";
- }
- } else {
- $consumer = new Zend_OpenId_Consumer();
- if ($consumer->verify($_GET, $id)) {
- $ret = true;
- $msg = "Authentifizierung erfolgreich";
- } else {
- $ret = false;
- $msg = "Authentifizierung fehlgeschlagen";
- }
- }
- return new Zend_Auth_Result($ret, $id, array($msg));
- }
- }
- $status = "";
- $auth = Zend_Auth::getInstance();
- if ((isset($_POST['openid_action']) &&
- $_POST['openid_action'] == "login" &&
- !empty($_POST['openid_identifier'])) ||
- isset($_GET['openid_mode'])) {
- $adapter = new OpenIdAdapter(@$_POST['openid_identifier']);
- $result = $auth->authenticate($adapter);
- if ($result->isValid()) {
- Zend_OpenId::redirect(Zend_OpenId::selfURL());
- } else {
- $auth->clearIdentity();
- foreach ($result->getMessages() as $message) {
- $status .= "$message<br>\n";
- }
- }
- } else if ($auth->hasIdentity()) {
- if (isset($_POST['openid_action']) &&
- $_POST['openid_action'] == "logout") {
- $auth->clearIdentity();
- } else {
- $status = "Du bist angemeldet als " . $auth->getIdentity() . "<br>\n";
- }
- }
- ?>
- <html><body>
- <?php echo htmlspecialchars($status);?>
- <form method="post"><fieldset>
- <legend>OpenID Login</legend>
- <input type="text" name="openid_identifier" value="">
- <input type="submit" name="openid_action" value="login">
- <input type="submit" name="openid_action" value="logout">
- </fieldset></form></body></html>
- ]]></programlisting>
- </example>
- <para>
- Mit <classname>Zend_Auth</classname> wird die Identität des End-Benutzes in den Session Daten gespeichert.
- Sie kann mit <classname>Zend_Auth::hasIdentity</classname> und <classname>Zend_Auth::getIdentity</classname>
- geprüft werden.
- </para>
- </sect2>
- <sect2 id="zend.openid.consumer.mvc">
- <title>Integration mit Zend_Controller</title>
- <para>
- Zuletzt ein paar Worte über die Integration in Model-View-Controller Anwendungen: Solche
- Zend Framework Anwendungen werden implementiert durch Verwenden der <classname>Zend_Controller</classname>
- Klasse und Sie verwenden die <classname>Zend_Controller_Response_Http</classname> Klasse um HTTP Antworten
- vorzubereiten und an den Web Browser des Benutzers zurückzusenden.
- </para>
- <para>
- <classname>Zend_OpenId_Consumer</classname> bietet keine GUI Möglichkeiten aber es führt HTTP Umleitungen
- bei erflgreichen <classname>Zend_OpenId_Consumer::login</classname> und
- <classname>Zend_OpenId_Consumer::check</classname> durch. Diese Umleitungen könnten nicht richtig funktionieren,
- oder sogar überhaupt nicht, wenn einige Daten bereits an den Web Browser gesendet wurden. Um
- HTTP Umleitungen im MVC Code richtig durchzuführen sollte die echte
- <classname>Zend_Controller_Response_Http</classname> als letztes Argument an
- <classname>Zend_OpenId_Consumer::login</classname> oder <classname>Zend_OpenId_Consumer::check</classname> gesendet
- werden.
- </para>
- </sect2>
- </sect1>
- <!--
- vim:se ts=4 sw=4 et:
- -->
|