| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 15617 -->
- <!-- 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 language="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 language="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 language="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 language="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 language="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 language="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 language="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 language="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 language="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 language="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:
- -->
|