Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs
ASP German Homepage Homepage
 

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Formularbasierte Authentifizierung in fünf Minuten

Geschrieben von: Christoph Wille
Kategorie: ASP.NET

In Anlehnung an diverse Buchserien werde ich Ihnen heute zeigen, wie schnell man mit ASP.NET eine Website für registrierte User erstellen kann. Da mir nach den fünf Minuten noch Zeit übrig bleibt, gebe ich Ihnen noch eine fix und fertige Lösung für ein technisch sauberes und vor allem sicheres Loginformular mit auf den Weg.

ASP.NET ist in vielen Bereichen revolutionär, so auch bei der Authentifizierung und der Authorisierung. Um die Begriffe zu definieren: Authentifizierung ist die Überprüfung ob der User der ist, der er vorgibt zu sein, und Authorisierung ist der Vorgang der Überprüfung ob der authentifizierte User auf eine bestimmte Resource zugreifen darf. Beide - Authentifizierung und Authorisierung - können je nach Bedarf durch eigene Implementationen ausgetauscht werden. Wir beschäftigen uns heute mit der am Web üblichsten Methode der Authentifizierung: formularbasierte Logins.

In klassischem ASP hat man eine geschlossene Webapplikation nach folgendem Muster entwickelt:

  • Ein Loginformular - die Authentifizierung.
  • Eine Includedatei - die Authorisierung. Diese Includedatei wurde in alle zu schützenden ASP Dateien includet, und hat die Benutzerberechtigungen auf Dateien überprüft.

Der Nachteil dieser Lösung ist klarerweise daß man alle ASP Dateien modifizieren muß. Mit ASP.NET ist das nicht mehr notwendig, wie ich Ihnen zeigen werde.

Die Implementation

Ich habe Ihnen versprochen, daß Sie innerhalb von fünf Minuten eine mit Forms-based Authentication gesicherte Webapplikation bekommen. Beginnen wir also, und zwar mit tatkräftiger Hilfe des ASP.NET Web Matrix Projekts. Wir benötigen zwei Dinge: eine web.config und ein passendes Loginformular. Beginnen wir damit, in einem neuen Verzeichnis namens basicformauth eine web.config anzulegen:

Der geübte Leser ahnt bereits, daß die Technik des heutigen Artikels wieder einmal "gewußt wo" lautet. Stimmt, das ASP.NET Web Matrix Projekt legt uns eine für formularbasierte Authentifizierung perfekt geeignete web.config an (Details zu web.config finden Sie im Artikel Web.Config 101)::

<?xml version="1.0" encoding="UTF-8" ?>

<configuration>

  <system.web>

    <authentication mode="Forms">
      <forms name=".ASPXAUTH" loginUrl="login.aspx" />
    </authentication>  
    
    <authorization>
      <deny users="?" /> 
    </authorization>

  </system.web>

</configuration>

Die springenden Punkte sind die authentication und authorization Nodes. Erstere legt die Art der Authentication (Forms) fest, zweitere sorgt dafür, daß anonymer Zugriff (?) auf unser Web nicht erlaubt ist, also Eintritt nur über das Loginformular gestattet ist. Dieses wird in der authentication Node definiert, und muß von "uns" angelegt werden:

Mit dieser Vorlage bekommen wir ein fix & fertiges Loginformular, das im Designer so aussieht:

Bevor wir uns den Code ansehen, müssen wir noch sicherstellen daß unsere web.config auch ihren Dienst verrichten kann. Da wir Authentifizierung verlangen, müssen wir das neu erstellte Verzeichnis zu einem Applikationsroot machen. Dies geschieht im ISM, Eigenschaften des Verzeichnisses, Applikation anlegen. Danach hat das Verzeichnis ein Paketsymbol vorangestellt:

Nun legen Sie sich eine Testdatei an, in meinem Fall ist das coolpage.aspx. Gehen Sie mit dem Webbrowser auf diese Seite, und voila, Sie landen auf der Loginseite! Auftrag ausgeführt, unsere Applikation ist nur mehr für berechtigte User zugänglich - aber halt, wer sind denn die Berechtigen?

Dazu sehen wir uns den Code der login.aspx an:

<%@ Page Language="C#" %>
<script runat="server">
    void LoginBtn_Click(Object sender, EventArgs e) {
    
        if (Page.IsValid) {
            if ((UserName.Text == "jdoe@somewhere.com") && (UserPass.Text == "password")) {
                FormsAuthentication.RedirectFromLoginPage(UserName.Text, true);
            }
            else {
                Msg.Text = "Invalid Credentials: Please try again";
            }
        }
    }
</script>

Ja, im Moment kann nur ein einzelner User einloggen, und der ist noch dazu fest verdrahtet. Damit kommen wir zu Teil 2 des Artikels: der technisch sauberen und vor allem sicheren Lösung für das Loginformular.

Formularbasierter Login mit Datenbank

In den meisten aller Fälle wird man die Benutzerkonten in einer Datenbank ablegen. Dafür möchte ich Ihnen heute eine "Best Practice" zur Verwendung in Ihren Applikationen mitgeben: technisch sauber, und vor allem sicher.

Als Datenbank habe ich eine einfache Accessdatenbank mit einer einzigen Tabelle gewählt, damit man später leicht auf andere Datenbankprodukte migrieren kann. Die Tabelle sieht so aus:

Den Datenbankconnectionstring speichere ich wie in Artikel Einstellungssache - Applikationsdaten in web.config gezeigt in der web.config, zusätzlich zu den bereits bestehenden Eintragungen:

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
  <system.web>

    <authentication mode="Forms">
      <forms name=".ASPXAUTH" loginUrl="login.aspx" />
    </authentication>  
    
    <authorization>
      <deny users="?" /> 
    </authorization>

    <!-- Bei Fehlern die nachfolgende Zeile von Kommentarzeichen "befreien"
         um die vollständige Fehlermeldung angezeigt zu bekommen. Auf "Live-Systemen"
         niemals debug="true" eingeschaltet lassen!!! -->

    <!-- <compilation debug="true"/> -->
  </system.web>

  <appSettings>
     <add key="LoginDb" value="PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=f:\aspheute\login.mdb" />
  </appSettings>
</configuration>

Andere Connection Strings, zB für SQL Server können Sie im Artikel Datenbankzugriff mittels ADO.NET nachlesen. Die weitere Änderung betrifft unser Loginformular login.aspx. Dort müssen wir die Methode LoginBtn_Click deutlich umbauen:

    void LoginBtn_Click(Object sender, EventArgs e) 
    {
        if (Page.IsValid) 
        {
            // holen des Connection Strings aus den <appSettings>
            string strDbConnString = ConfigurationSettings.AppSettings["LoginDb"];
            
            // verbinden zur Datenbank
            OleDbConnection con = new OleDbConnection(strDbConnString);
            con.Open();
            
            // SQL Injection sicher nicht mit uns!
            OleDbCommand cmd = new OleDbCommand();
            cmd.CommandText = "SELECT COUNT(*) FROM login WHERE UPN=@ParamUpn AND Password=@ParamPwd";
            cmd.Parameters.Add("@ParamUpn", UserName.Text);
            cmd.Parameters.Add("@ParamPwd", UserPass.Text);
            cmd.Connection = con;
            
            // korrektes Auslesen des mit ExecuteScalar geholten Wertes
            int nUsersMatched = 0;
            object oResult = cmd.ExecuteScalar();
            if (oResult != null) nUsersMatched = (int)oResult;
			
            // Command & Connection so früh als möglich schließen
            cmd.Dispose();
            con.Close();
            
            if (0 != nUsersMatched) {
                FormsAuthentication.RedirectFromLoginPage(UserName.Text, true);
            }
            else {
                Msg.Text = "Invalid Credentials: Please try again";
            }
        }
    }

Mit dem Aufruf von ConfigurationSettings.AppSettings holen wir uns den Connection String aus web.config. Mit diesem Connection String bauen wir eine OleDbConnection auf. Danach gehen wir absolut auf Nummer sicher: anstatt den SQL String dynamisch zusammenzubauen, verwenden wir eine parametrisierte Abfrage. Mehr dazu können Sie im Artikel Verhinderung von SQL Injection Marke .NET nachlesen, beziehungsweise sich im Artikel SQL Injection über die Hintergründe informieren.

Die parametrisierte Abfrage liefert uns 0 wenn die Logindaten inkorrekt sind, beziehungsweise 1 wenn der User authentifiziert werden konnte. Das Auslesen des Rückgabewerts von ExecuteScalar sollte man übrigens immer so wie gezeigt machen, und ebenfalls sollten alle verwendeten Resourcen (OleDbCommand und OleDbConnection) so schnell als möglich freigegeben werden.

Abschließend ist die orginale if Bedingung getauscht, der Code in der if Verzweigung selbst ist unverändert. Damit hätten wir dieses Kochrezept für ein datenbankgestütztes Loginformular auch schon abgeschlossen. Wollen Sie SQL Server einsetzen, so machen Sie eine Replaceoperation auf OleDb und tauschen alle Matches gegen Sql aus!

Schlußbemerkung

Formularbasierte Authentifizierung ist mit ASP.NET kinderleicht und vor allem schnell implementiert. Die vorgestellte Datenbanklösung können Sie für Ihre Applikationen als Startpunkt nehmen, da von vorne bis hinten auf Sicherheit geachtet wurde.

Download des Codes

Klicken Sie hier, um den Download zu starten.

Verwandte Artikel

Das ASP.NET Web Matrix Projekt
Datenbankzugriff mittels ADO.NET
Datentypen in C#
Einführung in ASP.NET Validation Controls (Teil 1)
Einführung in ASP.NET Validation Controls (Teil 2)
Einführung in ASP.NET Web Forms
Einstellungssache - Applikationsdaten in web.config
Einstieg in Visual Studio.NET - die erste Webanwendung mit Visual C#
Eventbehandlung bei ASP.NET WebForms
Exception Handling in C#
Kontrollstatements in C#
MS IE WebControls 101
Performancemessungen in .NET
Sichere Konvertierungen von Referenztypen
SQL Injection
Tracing in ASP.NET
Vergleich von DataGrid, DataList und Repeater-Control - was verwende ich wann?
Verhinderung von SQL Injection Marke .NET
Web.Config 101

Wenn Sie jetzt Fragen haben...

Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten.

Eine weitere sehr hilfreiche Resource ist das deutsche ASP.NET Wiki, das als zentrale Anlaufstelle für Tips, Tricks, Know How und alles Nützliche was man in seinem Alltag als (ASP).NET-Entwickler so braucht und entdeckt gedacht ist.

Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.

 

Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.