<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://www.aspnetzone.de/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Peter Bucher : HttpHandler</title><link>http://www.aspnetzone.de/blogs/peterbucher/archive/tags/HttpHandler/default.aspx</link><description>Ordnungsbegriffe: HttpHandler</description><dc:language /><generator>CommunityServer 2.1 SP2 (Build: 61120.2)</generator><item><title>Basic Authentication mit ASP.NET</title><link>http://www.aspnetzone.de/blogs/peterbucher/archive/2008/10/17/basic-authentication-mit-asp-net.aspx</link><pubDate>Fri, 17 Oct 2008 12:55:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:203199</guid><dc:creator>Peter Bucher</dc:creator><slash:comments>4</slash:comments><comments>http://www.aspnetzone.de/blogs/peterbucher/comments/203199.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/peterbucher/commentrss.aspx?PostID=203199</wfw:commentRss><description>&lt;P&gt;&lt;STRONG&gt;Möglichkeiten der Authentifizierung mit ASP.NET&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Mit ASP.NET gibt es verschiedene Möglichkeiten, sich am Server anzumelden, die bekannteste davon ist die Möglichkeit über Membership-API von ASP.NET.&lt;/P&gt;
&lt;P&gt;Zudem gibt es noch die Möglichkeiten, sich direkt am IIS zu authentifizieren, sei dies über "Integrated", "Digest" oder "Basic".&lt;/P&gt;
&lt;P&gt;Bei einer Autentifizierung über die Membership-API braucht es ein grosses Gerüst, eine Datenquelle sowie mindestens einen Membership-Provider, optional noch einen Role-Provider. &lt;BR&gt;Wenn keine Datenbank verfügbar ist, bzw. keine die direkt von der Membership-API unterstützt wird, muss ein eigener Provider geschrieben werden, dies gibt einen Mehraufwand und ist nicht in allen Fällen die richtige Lösung.&lt;/P&gt;
&lt;P&gt;Die Membership-API bietet standardmässig nur die Autentifizierungsoptionen "None, Forms, Windows oder Passport. &lt;BR&gt;All diese Möglichkeiten benötigen in der Standardkonfiguration eine &lt;A href="http://de.wikipedia.org/wiki/Grafische_Benutzeroberfl%C3%A4che"&gt;GUI&lt;/A&gt; für die Anmeldung und Verwaltung.&lt;/P&gt;
&lt;P&gt;An dieser Stelle sollte noch die Möglichkeit erwähnt werden, eine eigene API für die Benutzerverwaltung zu schreiben, falls sich die Membership-API nicht lohnt / zu gross ist.&lt;/P&gt;
&lt;P&gt;Ein Beispiel finden sie auf dem &lt;A href="http://www.aspnetzone.de/blogs/juergengutsch/"&gt;Blog&lt;/A&gt; von Jürgen Gutsch: &lt;A href="http://www.aspnetzone.de/blogs/juergengutsch/archive/2008/07/07/einfache-authentifizierung-mit-asp-net.aspx"&gt;Einfache Authentifizierung mit ASP.NET&lt;/A&gt;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Authentifizierung ohne eigene GUI&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Mit eigenen &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2007/11/20/daten-mit-asp-net-zum-client-schicken-oder-wieso-eigentlich-httphandler.aspx"&gt;HttpHandlers&lt;/A&gt; lassen sich nicht nur Ressourcen-Downloads abbilden (Dateien, CSS, Javascript, ..), sondern auch komplette Webseiten. &lt;BR&gt;(Merke: Die Basisklasse für eine ASP.NET Seite _Page_ ist auch ein HttpHandler, sprich: implementiert auch das Interface &lt;A href="http://msdn.microsoft.com/de-de/library/system.web.ihttphandler(VS.80).aspx"&gt;IHttpHandler&lt;/A&gt;)&lt;/P&gt;
&lt;P&gt;Eine Möglichkeit wie sowas umgesetzt werden könnte, wurde in diesem Blog schon mal &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/02/04/httphandler-der-besonderen-art-page-handler.aspx"&gt;erwähnt&lt;/A&gt;, daneben könnte eine komplette Webapplikation mithilfe einer HttpHandlerFactory (&lt;A href="http://msdn.microsoft.com/de-de/library/system.web.ihttphandlerfactory.aspx"&gt;IHttpHandlerFactory&lt;/A&gt;) aufgebaut werden, dazu aber in einem anderem Beitrag mehr.&lt;/P&gt;
&lt;P&gt;Wenn jetzt ein fertiger HttpHandler besteht, der von der eigentlichen Seiteninfrastruktur losgelöst ist und dessen Aufrufe Passwort geschützt werden müssen, was dann? &lt;BR&gt;Bei keiner Loslösung zur eigentlichen Applikation kann dessen Authentifizierung genutzt werden - also eine Anmeldung am System und dann Zugriff mittels Session oder Cookie.&lt;/P&gt;
&lt;P&gt;Ist dies aber nicht der Fall, kann diese Lücke mit der HTTP Basic Autentification gefüllt werden.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Basic Authentification?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Das HTTP-Protokoll selber sieht eine einfache Möglichkeit zur Authentifizierung vor, die Basic Authentifizierung. &lt;BR&gt;Wenn auf eine Ressource zugegriffen wird, die geschützt ist, wird beispielsweise folgender Header zum Browser geschickt:&lt;/P&gt;
&lt;DIV class=Quotes&gt;
&lt;P&gt;&lt;STRONG&gt;HTTP/1.1 401 Unauthorized&lt;/STRONG&gt; &lt;BR&gt;Server: Microsoft-IIS/6.0 &lt;BR&gt;Date: Fr, 17 Oct 2008 10:22:44 GMT &lt;BR&gt;&lt;STRONG&gt;WWW-Authenticate: BASIC Realm=Download Area&lt;/STRONG&gt; &lt;BR&gt;Connection: Keep-Alive &lt;BR&gt;Content-Length: 443 &lt;BR&gt;Content-Type: application/pdf &lt;BR&gt;Cache-control: private&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Der Statuscode "401 Unauthorized" + der Header "WWW-Authenticate" + "Basic " sagt dem Browser, dass er ein Loginfenster, wie vom guten alten Verzeichnisschutz mit dem IIS bekannt ist, darstellen soll. &lt;BR&gt;Dort wird ein Benutzername + Passwort eingegeben und bei Bestätigung durch [OK] zum Server gesendet. &lt;BR&gt;Das Versenden geschieht im Klartext, die Benutzernamen- Passwortkombination ist lediglich &lt;A href="http://de.wikipedia.org/wiki/Base64"&gt;Base64&lt;/A&gt; codiert.&lt;/P&gt;
&lt;P&gt;Auf dem Server wird die Kombination wiederum encodiert und geprüft. &lt;BR&gt;Falls die Prüfung erfolgreich ist, wird anstelle des beschrieben Statuscodes sowie dem WWWAuthenticate-Header der eigentliche Inhalt zum Client geschickt.&lt;/P&gt;
&lt;P&gt;Soweit die einfache Ausführung. Wie bei einer &lt;A href="http://www.aspnetzone.de/blogs/juergengutsch/archive/2008/07/07/einfache-authentifizierung-mit-asp-net.aspx"&gt;einfachen Authentifizierung mit ASP.NET&lt;/A&gt; kann auch hier Gebrauch vom &lt;A href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/09/14/asp-net-grundlagen-teil-2-tsch-ss-statuslosigkeit.aspx"&gt;Cookies&lt;/A&gt; gemacht werden, um so eine Anmeldung für einen weiteren Besuch aufrecht zu erhalten.&lt;/P&gt;
&lt;P&gt;Eine Aufrechterhaltung mithilfe des SessionStates ist nicht nötig, da sich die Browser das letze Login merken und daher für die Dauer einer Sitzung keine weitere Eingabe mehr nötig ist, wenn nicht eine andere Kennung erforderlich ist.&lt;/P&gt;
&lt;P&gt;Hinweis: &lt;BR&gt;Beim IIS7 funktioniert das beschriebene Vorgehen in der Standardeinstellung, beim IIS6 hingegen ist in der Standardeinstellung "Integrated Windows Authentication" an, dann versucht der IIS die Anfrage selbst zu bearbeiten. &lt;BR&gt;Bei den meisten Web-Providern sollte diese Einstellung standardmässig aus sein - einfach mal probieren.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="BORDER-BOTTOM:0px;BORDER-LEFT:0px;BORDER-TOP:0px;BORDER-RIGHT:0px;" border=0 alt=iis6_setting src="http://www.aspnetzone.de/blogs/peterbucher/WindowsLiveWriter/BasicAuthenticationmitASP.NET_11950/iis6_setting_6.png" width=371 height=334&gt; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Beispiel?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Folgend werden sie in ein Beispiel eingeführt das die Downloads im App_Code-Ordner hält (Dadurch vom Client nicht direkt abrufbar, also geschützt) und Zugriff auf die Downloads durch einen Handler gegen Eingabe der richtigen Benutzernamen- / Passwortkombination gewährt.&lt;/P&gt;
&lt;P&gt;Der HttpHandler im Beispiel hat zwei Methoden, neben der Implementierung vom IHttpHandler-Interface. &lt;BR&gt;Wenn ein Request eintrifft, werden in der Methode "CheckLogin" jeweils die Daten in der Servervariable "HTTP_AUTHORIZATION" abgefragt. &lt;BR&gt;Diese Daten enthalten im Falle einer Übergabe von Logindaten (Also wenn der Benutzer Benutzername und Passwort eingegeben hat) beispielsweise folgende Zeichenfolge:&lt;/P&gt;
&lt;DIV class=Quotes&gt;Basic YWRtaW46cHdk &lt;/DIV&gt;
&lt;P&gt;"Basic " ist die Kennung, dass es sich um die Basic Authentication handelt und die Zeichenfolge dahinter ist der Benutzername und das Password mit Base64 codiert. &lt;BR&gt;Wenn diese Zeichenfolge decodiert wird, könnte sie beispielsweise so aussehen:&lt;/P&gt;
&lt;DIV class=Quotes&gt;admin:pass &lt;/DIV&gt;
&lt;P&gt;Aufgrund dieser Daten wird das Login überprüft, bei Erfolg die Datei zum Client geschickt und bei Misserfolg wiederum im Header die Daten geschickt, dass der Client sich identifizieren muss.&lt;/P&gt;
&lt;P&gt;Dabei ist nur der Statuscode 401 + der Header nötig, die Ausgabe per Response.Write() ist optional. &lt;BR&gt;"Realm" steht für den Bereich der gesichert wird, im Beispiel einfach "Download Area".&lt;/P&gt;
&lt;DIV class=CodeBox&gt;&lt;code&gt;&lt;span style="color: Black;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt; &lt;br /&gt;&lt;br /&gt;&lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;namespace&lt;/span&gt; BasicAuthExample.Classes &lt;br /&gt;{ &lt;br /&gt;    &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;class&lt;/span&gt; SecureHandler : IHttpHandler &lt;br /&gt;    { &lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;#region&lt;/span&gt; IHttpHandler Members &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; ProcessRequest(HttpContext context) { &lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Login Checken &lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt;(CheckLogin(context)) { &lt;br /&gt;                &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Datei zum Client schicken &lt;/span&gt;&lt;br /&gt;                context.Response.ContentType &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"application/octet-stream"&lt;/span&gt;; &lt;br /&gt;                context.Response.AddHeader(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"content-disposition"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"attachment; filename=test.txt"&lt;/span&gt;); &lt;br /&gt;                context.Response.WriteFile(context.Server.MapPath(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"~/App_Data/secure.txt"&lt;/span&gt;)); &lt;br /&gt;            } &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;else&lt;/span&gt; { &lt;br /&gt;                &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Authentifizierung anfordern &lt;/span&gt;&lt;br /&gt;                RequestAuth(context); &lt;br /&gt;            } &lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;public&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;bool&lt;/span&gt; IsReusable { &lt;br /&gt;            get { &lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;false&lt;/span&gt;; &lt;br /&gt;            } &lt;br /&gt;        } &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;#endregion&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;bool&lt;/span&gt; CheckLogin(HttpContext context) {&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Infos vom Client (Name / Passwort)&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; data &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; context.Request.ServerVariables[&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"HTTP_AUTHORIZATION"&lt;/span&gt;] ?? String.Empty;&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Sind Daten einer Basic Authentifizierung vorhanden?&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;bool&lt;/span&gt; isAuthenticationDataAvailable &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt;&lt;br /&gt;                data !&lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; String.Empty &amp;amp;&amp;amp; data.IndexOf(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Basic"&lt;/span&gt;) &amp;gt; -1;&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Wenn keine Daten vorhanden sind, ist das Login fehlgeschlagen&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt; (!isAuthenticationDataAvailable) {&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;false&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Ansonsten Passwort und Namen decodieren und extrahieren&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; encodedAsBase64 &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; data.Replace(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"Basic "&lt;/span&gt;, String.Empty);&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;byte&lt;/span&gt;[] plainText &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; Convert.FromBase64String(encodedAsBase64);&lt;br /&gt;            UTF8Encoding encoding &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;new&lt;/span&gt; UTF8Encoding();&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; encodedAsUtf8 &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; encoding.GetString(plainText);&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Checken ob ein Doppelpunkt vorhanden ist&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;int&lt;/span&gt; indexOfColon &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; encodedAsUtf8.IndexOf(':');&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt; (indexOfColon == -1) {&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;false&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Ansonsten Passwort und Namen decodieren und extrahieren&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; username &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; encodedAsUtf8.Substring(0, indexOfColon);&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;string&lt;/span&gt; password &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; encodedAsUtf8.Substring(indexOfColon &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;+&lt;/span&gt; 1);&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Checken ob das Login korrekt ist&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;if&lt;/span&gt; (username.Equals(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"admin"&lt;/span&gt;) &amp;amp;&amp;amp; password.Equals(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"pass"&lt;/span&gt;)) {&lt;br /&gt;                &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;true&lt;/span&gt;;&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: Green;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;// Login fehlgeschlagen&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;return&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;false&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;private&lt;/span&gt; &lt;span style="color: Blue;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;void&lt;/span&gt; RequestAuth(HttpContext context) { &lt;br /&gt;            context.Response.Write(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"401 Unauthorized"&lt;/span&gt;); &lt;br /&gt;            context.Response.Status &lt;span style="color: Red;background-color: Transparent;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;=&lt;/span&gt; &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"401 Unauthorized"&lt;/span&gt;; &lt;br /&gt;            context.Response.AddHeader(&lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"WWW-Authenticate"&lt;/span&gt;, &lt;span style="color: #666666;background-color: #e4e4e4;font-family: Courier New;font-size: 14px;font-weight: normal;"&gt;"BASIC Realm=Download Service"&lt;/span&gt;); &lt;br /&gt;            context.Response.End(); &lt;br /&gt;        } &lt;br /&gt;    } &lt;br /&gt;}&lt;/span&gt;&lt;/code&gt; &lt;/DIV&gt;
&lt;P&gt;&lt;STRONG&gt;Wann ist diese Art der Authentifizierung jetzt überhaupt sinnvoll?&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Diese Frage ist durch den ersten Teil des Artikels schon fast beantwortet. &lt;BR&gt;Bei einem HttpHandler - vorallem wenn er selber von der Hauptapplikation isoliert ist (Externe Library beispielsweise) - ist es nicht einfach möglich oder sinnvoll für die Anmeldung eine riesen Infrastruktur inklusive GUI hochzufahren.&lt;/P&gt;
&lt;P&gt;Genau bei einem solchen Fall, ist die Basic Authentifizierung ein guter Kandidat. &lt;BR&gt;Wenn es um wirklich sichere Daten geht, sieht diese Art der Authentifizierung jedoch alt aus, sofern keine SSL-Verschlüsselung im Spiel ist, da alles im Klartext übermittelt wird.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Abschliessende Worte&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Ich hoffe dieser Ausflug in die Authentifizierung mit ASP.NET bringt auch bei diesem Thema ein bisschen Licht ins Dunkle &lt;BR&gt;und wirft hoffentlich auch neue Fragen, Ideen und Diskussionen auf.&lt;/P&gt;
&lt;P&gt;Wie immer bin ich für alle Ideen, Vorschläge und jegliche konstruktive Kritik gerne zu haben, benutzt dazu einfach die Kommentarmöglichkeit dieses Blogs.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Download des Beispiels:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A href="http://www.aspnetzone.de/files/folders/203198/download.aspx"&gt;BasicAuthExample.zip&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Quellen:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;A title=http://www.aspheute.com/artikel/20010521.htm href="http://www.aspheute.com/artikel/20010521.htm"&gt;http://www.aspheute.com/artikel/20010521.htm&lt;/A&gt; &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;&lt;STRONG&gt;Bearbeitung / Korrekturen:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;08.01.09 - CheckLogin-Methode verbessert und Download upgedated&lt;/P&gt;&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=203199" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Artikel/default.aspx">Artikel</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/HttpHandler/default.aspx">HttpHandler</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Basic%20Authentication/default.aspx">Basic Authentication</category></item><item><title>Requestdauer mit einem HttpModule und Response.Filter ausgeben</title><link>http://www.aspnetzone.de/blogs/peterbucher/archive/2008/03/16/requestdauer-mit-einem-httpmodule-und-response-filter-ausgeben.aspx</link><pubDate>Sun, 16 Mar 2008 21:50:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:193331</guid><dc:creator>Peter Bucher</dc:creator><slash:comments>6</slash:comments><comments>http://www.aspnetzone.de/blogs/peterbucher/comments/193331.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/peterbucher/commentrss.aspx?PostID=193331</wfw:commentRss><description>Auf die Frage hin von Kristof auf der ASP.NET Zone , habe ich noch eine schönere und genauere Lösung gesucht, als sich in die Render Methode einer Seite einzuhängen. Gefordert war die Anzeige von der Dauer des gesamten Requests (Von BeginRequest bis EndRequest,...(&lt;a href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/03/16/requestdauer-mit-einem-httpmodule-und-response-filter-ausgeben.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=193331" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Artikel/default.aspx">Artikel</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/HttpHandler/default.aspx">HttpHandler</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Decorator/default.aspx">Decorator</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Logging/default.aspx">Logging</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Stream/default.aspx">Stream</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/HttpModule/default.aspx">HttpModule</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/HttpModules/default.aspx">HttpModules</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Design%20Patterns/default.aspx">Design Patterns</category></item><item><title>HttpHandler der besonderen Art - Page Handler</title><link>http://www.aspnetzone.de/blogs/peterbucher/archive/2008/02/04/httphandler-der-besonderen-art-page-handler.aspx</link><pubDate>Mon, 04 Feb 2008 19:09:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:191083</guid><dc:creator>Peter Bucher</dc:creator><slash:comments>2</slash:comments><comments>http://www.aspnetzone.de/blogs/peterbucher/comments/191083.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/peterbucher/commentrss.aspx?PostID=191083</wfw:commentRss><description>HttpHandler wurden von mir hier im Blog schon einmal erläutert und ein zweites Mal aufgegriffen . Es ist also möglich einen HttpHandler innerhalb eines Controls zu kapseln, das ist praktisch wenn ein Control in sich geschlossen eine Möglichkeit hat, einen...(&lt;a href="http://www.aspnetzone.de/blogs/peterbucher/archive/2008/02/04/httphandler-der-besonderen-art-page-handler.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=191083" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/IHttpHandler/default.aspx">IHttpHandler</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Page/default.aspx">Page</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/HttpHandler/default.aspx">HttpHandler</category></item><item><title>HttpHandler innerhalb eines Controls</title><link>http://www.aspnetzone.de/blogs/peterbucher/archive/2007/11/28/httphandler-innerhalb-eines-controls.aspx</link><pubDate>Wed, 28 Nov 2007 18:40:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:188408</guid><dc:creator>Peter Bucher</dc:creator><slash:comments>6</slash:comments><comments>http://www.aspnetzone.de/blogs/peterbucher/comments/188408.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/peterbucher/commentrss.aspx?PostID=188408</wfw:commentRss><description>Ich dachte lange Zeit das dies nicht möglich sei, jedoch ist es fast zu einfach um wahr zu sein :-) Okay zugegeben, es müssen schon spezielle Anwendungsfälle sein, um einen HttpHandler innerhalb eines Controls zu benötigen. Es braucht dazu zwei Schritte,...(&lt;a href="http://www.aspnetzone.de/blogs/peterbucher/archive/2007/11/28/httphandler-innerhalb-eines-controls.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=188408" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Tipps/default.aspx">Tipps</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Control%20Entwicklung/default.aspx">Control Entwicklung</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/WebResource.axd/default.aspx">WebResource.axd</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/web_2E00_config/default.aspx">web.config</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/IHttpHandler/default.aspx">IHttpHandler</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/HttpHandler/default.aspx">HttpHandler</category></item><item><title>Daten mit ASP.NET zum Client schicken, oder: Wieso eigentlich HttpHandler?</title><link>http://www.aspnetzone.de/blogs/peterbucher/archive/2007/11/20/daten-mit-asp-net-zum-client-schicken-oder-wieso-eigentlich-httphandler.aspx</link><pubDate>Tue, 20 Nov 2007 21:53:00 GMT</pubDate><guid isPermaLink="false">ce930855-ae9b-4fa4-8077-06a76071cc6a:187993</guid><dc:creator>Peter Bucher</dc:creator><slash:comments>9</slash:comments><comments>http://www.aspnetzone.de/blogs/peterbucher/comments/187993.aspx</comments><wfw:commentRss>http://www.aspnetzone.de/blogs/peterbucher/commentrss.aspx?PostID=187993</wfw:commentRss><description>Einführung Wenn per Browser eine Webseite abgerufen wird, sendet der Browser eine GET oder POST Anforderung an den Webserver zu einen bestimmten Identifier bzw. Adresse. Der Webserver schickt dann - aufgrund der Infos die per Request hineingekommen sind...(&lt;a href="http://www.aspnetzone.de/blogs/peterbucher/archive/2007/11/20/daten-mit-asp-net-zum-client-schicken-oder-wieso-eigentlich-httphandler.aspx"&gt;read more&lt;/a&gt;)&lt;img src="http://www.aspnetzone.de/aggbug.aspx?PostID=187993" width="1" height="1"&gt;</description><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Artikel/default.aspx">Artikel</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/IHttpHandler/default.aspx">IHttpHandler</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/Page/default.aspx">Page</category><category domain="http://www.aspnetzone.de/blogs/peterbucher/archive/tags/HttpHandler/default.aspx">HttpHandler</category></item></channel></rss>