| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- <?xml version="1.0" encoding="UTF-8"?>
- <!-- EN-Revision: 24249 -->
- <!-- Reviewed: no -->
- <sect1 id="zend.infocard.basics">
- <title>Einführung</title>
- <para>
- Die <classname>Zend_InfoCard</classname> Komponente implementiert die Unterstützung
- vertrauender Forderungen für Informationskarten. Informationskarten werden für
- Identitätsmanagement im Internet verwendet und zur Authentifikation von Benutzern auf
- Webseiten. Die Webseiten bei denen sich die Benutzer im Endeffekt authentifizieren werden
- <emphasis>vertrauende Seiten</emphasis> genannt.
- </para>
- <para>
- Detailierte Informationen über Informationskarten und Ihre Wichtigkeit für Internet
- Identitätsmetasysteme können im <ulink
- url="http://www.identityblog.com/">IdentityBlog</ulink> gefunden werden.
- </para>
- <sect2 id="zend.infocard.basics.theory">
- <title>Grundsätzliche Theorie der Verwendung</title>
- <para>
- <classname>Zend_InfoCard</classname> kann auf einem von zwei Wegen verwendet werden:
- Entweder als Teil der größeren <classname>Zend_Auth</classname> Komponente über den
- <classname>Zend_InfoCard</classname> Authentifikationsadapter order als eigenständige
- Komponente. In beiden Fällen kann eine Informationskarte von einem Benutzer angefragt
- werden durch Verwenden des folgenden <acronym>HTML</acronym> Blocks im eigenen
- <acronym>HTML</acronym> Anmeldeformular:
- </para>
- <programlisting language="html"><![CDATA[
- <form action="http://example.com/server" method="POST">
- <input type='image' src='/images/ic.png' align='center'
- width='120px' style='cursor:pointer' />
- <object type="application/x-informationCard"
- name="xmlToken">
- <param name="tokenType"
- value="urn:oasis:names:tc:SAML:1.0:assertion" />
- <param name="requiredClaims"
- value="http://.../claims/privatepersonalidentifier
- http://.../claims/givenname
- http://.../claims/surname" />
- </object>
- </form>
- ]]></programlisting>
- <para>
- Im obigen Beispiel wird das <property>requiredClaims</property>
- <emphasis><param></emphasis> Tag verwendet um Teile von Informationen zu
- identifizieren die als Forderung bekannt sind (z.B. der Vorname und Nachname einer
- Person) welche eine Webseite (genannt "vertrauende Forderung) benötigt um einen Benutzer
- authentifizieren zu können der eine Informationskarte verwendet. Zur Referenz, ist die
- komplette <acronym>URI</acronym> (zum Beispiel die <code>givename</code> Anforderung)
- wie folgt:
- <filename>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname</filename>
- </para>
- <para>
- Wenn das obige <acronym>HTML</acronym> durch einen Benutzer aktiviert wird (angeklickt),
- zeigt der Browser ein Kartenauswahlprogramm an, welche Ihm nicht nur die
- Informationskarten anzeigt die den Anforderungen der Seite entsprechen, sondern es auch
- erlaubt welche Informationskarte verwendet werden soll wenn mehrere den Kriterien
- entsprechen. Diese Informationskarte wird als <acronym>XML</acronym> Dokument zu der
- spezifizierten POST <acronym>URL</acronym> übertragen und steht dann zur Bearbeitung der
- <classname>Zend_InfoCard</classname> Komponente zur Verfügung.
- </para>
- <para>
- Beachte das Informationskarten nur zu <acronym>SSL</acronym>-verschlüsselten
- <acronym>URL</acronym>s <acronym>HTTP</acronym> <acronym>POST</acronym>et werden können.
- Die Dokumentation des WebServers sollte konsultiert werden für Details zum Einrichten
- einer <acronym>SSL</acronym> Verschlüsselung.
- </para>
- </sect2>
- <sect2 id="zend.infocard.basics.auth">
- <title>Verwendung als Teil von Zend_Auth</title>
- <para>
- Um diese Komponente als Teil des <classname>Zend_Auth</classname>
- Authentifikationssystems zu verwenden, muß die angebotene
- <classname>Zend_Auth_Adapter_InfoCard</classname> verwendet werden (in der standalone
- Distribution von <classname>Zend_InfoCard</classname> nicht enthalten). Ein Beispiel der
- Verwendung wird anbei gezeigt:
- </para>
- <programlisting language="php"><![CDATA[
- <?php
- if (isset($_POST['xmlToken'])) {
- $adapter = new Zend_Auth_Adapter_InfoCard($_POST['xmlToken']);
- $adapter->addCertificatePair('/usr/local/Zend/apache2/conf/server.key',
- '/usr/local/Zend/apache2/conf/server.crt');
- $auth = Zend_Auth::getInstance();
- $result = $auth->authenticate($adapter);
- switch ($result->getCode()) {
- case Zend_Auth_Result::SUCCESS:
- $claims = $result->getIdentity();
- print "Angegebener Name: {$claims->givenname}<br />";
- print "Vorname: {$claims->surname}<br />";
- print "Email Adresse: {$claims->emailaddress}<br />";
- print "PPI: {$claims->getCardID()}<br />";
- break;
- case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
- print "Die angegebenen Daten haben der Überprüfung "
- . "nicht standgehalten";
- break;
- default:
- case Zend_Auth_Result::FAILURE:
- print "Bei der Bearbeitung der Angaben trat ein Fehler auf.";
- break;
- }
- if (count($result->getMessages()) > 0) {
- print "<pre>";
- var_dump($result->getMessages());
- print "</pre>";
- }
- }
- ?>
- <hr />
- <div id="login" style="font-family: arial; font-size: 2em;">
- <p>Einfache Anmeldungsdemo</p>
- <form method="post">
- <input type="submit" value="Login" />
- <object type="application/x-informationCard" name="xmlToken">
- <param name="tokenType"
- value="urn:oasis:names:tc:SAML:1.0:assertion" />
- <param name="requiredClaims"
- value="http://.../claims/givenname
- http://.../claims/surname
- http://.../claims/emailaddress
- http://.../claims/privatepersonalidentifier" />
- </object>
- </form>
- </div>
- ]]></programlisting>
- <para>
- Im obigen Beispiel wurde zuerst eine Instanz von
- <classname>Zend_Auth_Adapter_InfoCard</classname> erstellt und die durch die
- Kartenauswahl geschickten <acronym>XML</acronym> Daten an Ihn übergeben. Sobald die
- Instanz erstellt wurde muß zumindest ein <acronym>SSL</acronym>
- Zertifizieruntsschlüssel, ein Paar öffentlich/privat der vom Webserver verwendet wird,
- übergeben werden der mit <acronym>HTTP</acronym> <acronym>POST</acronym> empfangen
- wurde. Diese Dateien werden verwendet um das Ziel der Information das an den Server
- geschickt wurde zu überprüfen und sind eine Notwendigkeit wenn Informationskarten
- verwendet werden.
- </para>
- <para>
- Sobald der Adapter konfiguriert wurde können die normalen Fähigkeiten von
- <classname>Zend_Auth</classname> verwendet werden um das angegebene Token der
- Informationskarte zu prüfen und den Benutzer, durch Betrachten der Identität die von der
- <methodname>getIdentity()</methodname> Methode geboten wird, zu authentifizieren.
- </para>
- </sect2>
- <sect2 id="zend.infocard.basics.standalone">
- <title>Die Zend_InfoCard Komponente alleine verwenden</title>
- <para>
- Es ist auch möglich die <classname>Zend_InfoCard</classname> Komponente als
- alleinstehende Komponente zu verwenden durch direkte Interaktion mit der
- <classname>Zend_InfoCard</classname> Klasse. Die Verwendung der Zend_InfoCard Klasse ist
- ähnlich der Verwendung durch die <classname>Zend_Auth</classname> Komponente. Ein
- Beispiel dieser Verwendung wird anbei gezeigt:
- </para>
- <programlisting language="php"><![CDATA[
- <?php
- if (isset($_POST['xmlToken'])) {
- $infocard = new Zend_InfoCard();
- $infocard->addCertificatePair('/usr/local/Zend/apache2/conf/server.key',
- '/usr/local/Zend/apache2/conf/server.crt');
- $claims = $infocard->process($_POST['xmlToken']);
- if($claims->isValid()) {
- print "Angegebener Name: {$claims->givenname}<br />";
- print "Vorname: {$claims->surname}<br />";
- print "Email Adresse: {$claims->emailaddress}<br />";
- print "PPI: {$claims->getCardID()}<br />";
- } else {
- print "Fehler bei der Prüfung der Identität: {$claims->getErrorMsg()}";
- }
- }
- ?>
- <hr />
- <div id="login" style="font-family: arial; font-size: 2em;">
- <p>Einfache Login Demo</p>
- <form method="post">
- <input type="submit" value="Login" />
- <object type="application/x-informationCard" name="xmlToken">
- <param name="tokenType"
- value="urn:oasis:names:tc:SAML:1.0:assertion" />
- <param name="requiredClaims"
- value="http://.../claims/givenname
- http://.../claims/surname
- http://.../claims/emailaddress
- http://.../claims/privatepersonalidentifier" />
- </object>
- </form>
- </div>
- ]]></programlisting>
- <para>
- Im obigen Beispiel wird die <classname>Zend_InfoCard</classname> Komponente unabhängig
- verwendet um den vom Benutzer angebotenen Token zu überprüfen. Die auch mit
- <classname>Zend_Auth_Adapter_InfoCard</classname>, wird zuerst eine Instanz von
- <classname>Zend_InfoCard</classname> erstellt und dann ein oder mehrere
- <acronym>SSL</acronym> Zertifikatschlüssel, ein Paar öffentlich/privat die vom Webserver
- verwendet werden. Sobald sie konfiguriert ist kann die
- <methodname>process()</methodname> Methode verwendet werden um die Informationskarte zu
- bearbeiten und die Ergebnisse zurückzugeben.
- </para>
- </sect2>
- <sect2 id="zend.infocard.basics.claims">
- <title>Mit einem Forderungs Objekt arbeiten</title>
- <para>
- Egal ob die <classname>Zend_InfoCard</classname> Komponente als alleinstehende
- Komponente oder als Teil von <classname>Zend_Auth</classname> über
- <classname>Zend_Auth_Adapter_InfoCard</classname> verwendet wird, ist das endgültige
- Ergebnis der Bearbeitung einer Informationskarte ein
- <classname>Zend_InfoCard_Claims</classname> Objekt. Dieses Objekt enthält die Annahmen
- (auch Forderungen genannt) die vom schickenden Benutzer gemacht wurden, basierend auf
- den Daten die von der Webseite angefragt wurden als sich der Benutzer authentifiziert
- hat. Wie im obigen Beispiel gezeigt, kann die Gültigkeit der Informationskarte
- sichergestellt werden indem die <methodname>Zend_InfoCard_Claims::isValid()</methodname>
- Methode aufgerufen wird. Forderungen ihrerseits können entweder empfangen werden indem
- auf den gewünschten Identikator zugegriffen wird (z.B. <property>givenname</property>)
- als eine Eigenschaft des Objekts oder durch die <methodname>getClaim()</methodname>
- Methode.
- </para>
- <para>
- In den meisten Fällen ist es nicht notwendig die <methodname>getClaim()</methodname>
- Methode zu verwenden. Wenn es <property>requiredClaims</property> trotzdem erfordert das
- Forderungen von verschiedenen unterschiedlichen Quellen/Namensräumen angefragt werden
- ist es notwendig diese explizit durch Verwendung dieser Methode zu extrahieren (indem
- einfach die komplette <acronym>URI</acronym> der Forderung übergeben wird, damit der
- Wert von der Informationskarte empfangen werden kann). Generell gesprochen, wird die
- <classname>Zend_InfoCard</classname> Komponente die Standard <acronym>URI</acronym> für
- Forderungen auf eine Setzen die am häufigsten in der Informationskarte selbst verwendet
- wird, und damit die vereinfachte Eigenschaft-Zugriffs Methode verwendet werden kann.
- </para>
- <para>
- Als Teil des Prüfprozesses ist es am Entwickler die ausgebende Quelle der Forderung zu
- prüfen die in der Informationskarte enthalten sind, und zu entscheiden ob diese Quelle
- eine vertrauenswürdige Quelle von Informationen ist. Um das zu tun gibt es die
- <methodname>getIssuer()</methodname> Methode die im
- <classname>Zend_InfoCard_Claims</classname> Objekt angeboten wird und die
- <acronym>URI</acronym> des Ausstellers der Forderung der Informationskarte zurückgibt.
- </para>
- </sect2>
- <sect2 id="zend.infocard.basics.attaching">
- <title>Informationskarten an bestehende Konten anhängen</title>
- <para>
- Es ist möglich Unterstützung für Informationskarten zu einem bestehenden
- Authentifizierungssystem hinzuzufügen durch Speicherung des privaten persönlichen
- Identifikators (PPI) zum vorher traditionell-authentifizierten Zugang und zumindest die
- <filename>http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier</filename>
- Forderung als Teil der <property>requiredClaims</property> der Anfrage zu inkludieren.
- Wenn diese Forderung angefragt wird, biete das
- <classname>Zend_InfoCard_Claims</classname> Objekt einen eideutigen Identifikator für
- diese spezielle Karte anzubieten die durch den Aufruf der
- <methodname>getCardID()</methodname> Methode übermittelt wurde.
- </para>
- <para>
- Ein Beispiel wie eine Informationskarte an einen traditionell-authentifizierten Zugang
- angehängt werden kann wird hier gezeigt:
- </para>
- <programlisting language="php"><![CDATA[
- // ...
- public function submitinfocardAction()
- {
- if (!isset($_REQUEST['xmlToken'])) {
- throw new ZBlog_Exception('Verschlüsselter Token erwartet ' .
- 'aber nicht übergeben');
- }
- $infoCard = new Zend_InfoCard();
- $infoCard->addCertificatePair(SSL_CERTIFICATE_PRIVATE,
- SSL_CERTIFICATE_PUB);
- try {
- $claims = $infoCard->process($request['xmlToken']);
- } catch(Zend_InfoCard_Exception $e) {
- // TODO Fehlerbehandung durch die Anfrage
- throw $e;
- }
- if ($claims->isValid()) {
- $db = ZBlog_Data::getAdapter();
- $ppi = $db->quote($claims->getCardID());
- $fullname = $db->quote("{$claims->givenname} {$claims->surname}");
- $query = "UPDATE blogusers
- SET ppi = $ppi,
- real_name = $fullname
- WHERE username='administrator'";
- try {
- $db->query($query);
- } catch(Exception $e) {
- // TODO Fehler beim Speichern in der DB
- }
- $this->view->render();
- return;
- } else {
- throw new
- ZBlog_Exception("Informationskarte hat die Sicherheitsprüfungen "
- . "nicht bestanden");
- }
- }
- ]]></programlisting>
- </sect2>
- <sect2 id="zend.infocard.basics.adapters">
- <title>Erstellung von Zend_InfoCard Adapter</title>
- <para>
- Die <classname>Zend_InfoCard</classname> Komponente wurde entwickelt um den Wachstum im
- Standard der Informationskarten durch die Verwendung einer modularen Architektur zu
- erlauben. Aktuell werden viele dieser Hooks nicht verwendet und können ignoriert werden.
- Aber es gibt einen Aspekt der in jeder seriösen Implementation von Informationskarten
- geschrieben werden sollte: Der <classname>Zend_InfoCard</classname> Adapter.
- </para>
- <para>
- Der <classname>Zend_InfoCard</classname> Adapter wird als Callback Mechanismus innerhalb
- der Komponente verwendet um verschiedenste Aufgaben durchzuführen, wie das Speichern und
- Empfangen von Assertion IDs für Informationskarten wenn diese von der Komponente
- bearbeitet werden. Wärend das Speichern der Assertion IDs von übertragenen
- Informationskarten nicht notwendig ist, kann das nicht Durchführen die Möglichkeit
- eröffnen, dass das Authentifizierungs Schema durch eine Replay Attacke kompromitiert
- wird.
- </para>
- <para>
- Um das zu verhindern muß <classname>Zend_InfoCard_Adapter_Interface</classname>
- implementiert werden und dann eine Instanz dieses Adapters vor dem Aufruf der
- <methodname>process()</methodname> (alleinstehend) oder
- <methodname>authenticate()</methodname> Methode (als ein
- <classname>Zend_Auth</classname> Adapter) gesetzt werden. Um dieses Interface zu setzen
- wird die <methodname>setAdapter()</methodname> Methode verwendet. Im Beispiel anbei wird
- ein <classname>Zend_InfoCard</classname> Adapter gesetzt und innerhalb der Anwendung
- verwendet:
- </para>
- <programlisting language="php"><![CDATA[
- class myAdapter implements Zend_InfoCard_Adapter_Interface
- {
- public function storeAssertion($assertionURI,
- $assertionID,
- $conditions)
- {
- /* Die durch ID und URI angegebene Assertion
- und Ihre Konditionen speichern */
- }
- public function retrieveAssertion($assertionURI, $assertionID)
- {
- /* Die durch URI und ID angegebene Assertion empfangen */
- }
- public function removeAssertion($assertionURI, $assertionID)
- {
- /* Die durch URI/ID angegebene Assertion löschen */
- }
- }
- $adapter = new myAdapter();
- $infoCard = new Zend_InfoCard();
- $infoCard->addCertificatePair(SSL_PRIVATE, SSL_PUB);
- $infoCard->setAdapter($adapter);
- $claims = $infoCard->process($_POST['xmlToken']);
- ]]></programlisting>
- </sect2>
- </sect1>
|