Hallo Rene und Jürgen,
besten Dank nochmal für Eure Anregungen. Ich habe einfach mal gemacht,
was Rene empfohlen hat, da ich schon einen rein CSS- getriebenen Site- Content
für User ohne JavaScript in einem extra Unterverzeichnis parat hatte:
1. Unterverzeichnis angelegt, darin PruefCsript.aspx erstellt
3. dieses in der Web. config location path.. -> allow user: all (*) konfiguriert
3. in der global.asax den session_start- Event mit response.redirect bestückt
4. Falls JavaScript deaktiviert ist, bekommt der User einen Weiterleitungshinweis,
entweder meta refresh -> Ziel ... oder Link auf die Noscript- Startseite, jedoch mit einem
URL- Paramter, den ich dann zwar nicht in der Loginseite behandele, jedoch in der
Code- Behind der Startseite auslese, um abermals weiterzuleiten.
Dat gefällt mir zwar noch nicht wirklich, ist aber erstmal brauchbar. Es kommt ja
nicht immer auf Schönheit an und vielleicht habe ich ja in absehbarer Zeit ein bischen
mehr Ahnung von det janze.
Vielleicht interessiert Euch ja dies mal als Tip von meiner Seite und vielleicht zur allgemeinen Veröffentlichung:
ACCESS- Mietgliedschaftsverwaltung einfach, ohne Website- Verwaltungstool und SQL-Server
Ich habe mal drüber nachgedacht, wie - anstatt das Website- Verwaltungstool für die Mitgliedschaft
zu verwenden und eine SQL Server- DB beim Provider attachen zu müssen - eine einfache ACCESS- Datenbank diese
ganze Anmelderei (gerade bei kleineren Webanwendungen) aber trotzdem mit allen Features
(darunter HASH1 Verschlüsselung) des standardmäßigen NET.SQL Membership Providers erledigen könnte.
Vorteil für kleine Anwendungen und Einsteiger wie mich in Sachen ASP.NET Webentwicklung:
Einfach eine Access- Datenbank beim Provider ins App_data- Verzeichnis hochladen können, ohne sich mit SQL- Instanzen,
dem Attached- Prozedere oder ODBC beim Provider herumschlagen zu müssen und trotzdem alle Features der Mitgliedschaft
nutzen können.
Ich also auf Microsoft MSDN für Developer geschaut, C#- Beispielcode für die ODBC- Mitgliedschaftsanbieterklasse kopiert
und einfach auf OleDb umgefummelt. (Habe die Klasse noch nicht als OleDb- Beispiel gefunden)
Ich verzichte hier darauf die komplette OleDb- Klasse zu posten, das wird zu lang denke ich, ich beschreibe stattdessen die
nötigen Anpassungen.
1. Anpassungen der Klasse für Odbc an die Verwendung mit OleDb
Zunächst müssen alle Cod-Teile "ODBC.." in der Klasse durch "OleDb" ersetzt werden, natürlich auch die using- Direktive.
Dies betrifft im Wesentlichen natürlich die .NET Instanzmember und die Datentypen.
Ich habe aus Gründen der Klarheit auch den Klassenbezeichner von "OdbcMembershipProvider" auf "OleDbMembershipProvider"
abgeändert. Die Klasse selbst erbt von .NET "System.Web.Security.MembershipProvider"
Beispiel- Ausschnitt zur immer wiederkehrenden SQL- Connection in der KLasse, Instanz-Member und Datentypen vorher mit Odbc...:
OdbcConnection conn = new OdbcConnection(connectionString); OdbcCommand cmd = new OdbcCommand("UPDATE Users " + " SET Password = ?, LastPasswordChangedDate = ? " + " WHERE Username = ? AND ApplicationName = ?", conn); cmd.Parameters.Add("@Password", OdbcType.VarChar, 255).Value = EncodePassword(newPwd); cmd.Parameters.Add("@LastPasswordChangedDate", OdbcType.DateTime).Value = DateTime.Now; cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username; cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName;
Ausschnitt nachher mit OleBb...:
OleDbConnection conn = new OleDbConnection(connectionString); OleDbCommand cmd = new OleDbCommand("UPDATE Users " + " SET Pasword = ?, LastPasswordChangedDate = ? " + " WHERE Username = ? AND ApplicationName = ?", conn); cmd.Parameters.Add("@Pasword", OleDbType.VarChar, 255).Value = EncodePassword(newPwd); cmd.Parameters.Add("@LastPasswordChangedDate", OleDbType.Date).Value = DateTime.Now; cmd.Parameters.Add("@Username", OleDbType.VarChar, 255).Value = username; cmd.Parameters.Add("@ApplicationName", OleDbType.VarChar, 255).Value = pApplicationName;
Ein wichtiger, aber feiner Unterschied ist zudem, dass unter OleDb manche Datentypen andere sind (bzw. heißen),
bspw. "DateTime"-> (Odbc) und "Date"-> (OleDb), diese müssen auch ersetzt werden
damit die Abfrage auf die ACCESS- Datenbank nicht fehlschlägt. (aber nur auf der linken Seite der Zuweisung, DateTime.Now bleibt wie es ist!)
Anmerkung:
Mit der einzusetzenden ACCESS- Datenbank (bei mir ist es ACCESS 2000-2003) sollte beim späteren Testen ggf. auch der Datentyp
einiger Felder mit den Abrage- Datentypen abgestimmt und eventuell geändert werden.
Was muß noch ersetzt werden?
Im folgenden Codeausschnitt werden darüber hinaus die Odbc- Datentypen "Bit" und "Int" verwendet,
diese müssen in der gesamtem Klasse durch "Boolean" und "Integer" ersetzt werden.
OdbcConnection conn = new OdbcConnection(connectionString); OdbcCommand cmd = new OdbcCommand("INSERT INTO Users " + " (PKID, Username, Password, Email, PasswordQuestion, " + " PasswordAnswer, IsApproved," + " Comment, CreationDate, LastPasswordChangedDate, LastActivityDate," + " ApplicationName, IsLockedOut, LastLockedOutDate," + " FailedPasswordAttemptCount, FailedPasswordAttemptWindowStart, " + " FailedPasswordAnswerAttemptCount, FailedPasswordAnswerAttemptWindowStart)" + " Values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", conn); cmd.Parameters.Add("@PKID", OdbcType.UniqueIdentifier).Value = providerUserKey; cmd.Parameters.Add("@Username", OdbcType.VarChar, 255).Value = username; cmd.Parameters.Add("@Password", OdbcType.VarChar, 255).Value = EncodePassword(password); cmd.Parameters.Add("@Email", OdbcType.VarChar, 128).Value = email; cmd.Parameters.Add("@PasswordQuestion", OdbcType.VarChar, 255).Value = passwordQuestion; cmd.Parameters.Add("@PasswordAnswer", OdbcType.VarChar, 255).Value = EncodePassword(passwordAnswer); cmd.Parameters.Add("@IsApproved", OdbcType.Bit).Value = isApproved; cmd.Parameters.Add("@Comment", OdbcType.VarChar, 255).Value = ""; cmd.Parameters.Add("@CreationDate", OdbcType.DateTime).Value = createDate; cmd.Parameters.Add("@LastPasswordChangedDate", OdbcType.DateTime).Value = createDate; cmd.Parameters.Add("@LastActivityDate", OdbcType.DateTime).Value = createDate; cmd.Parameters.Add("@ApplicationName", OdbcType.VarChar, 255).Value = pApplicationName; cmd.Parameters.Add("@IsLockedOut", OdbcType.Bit).Value = false; cmd.Parameters.Add("@LastLockedOutDate", OdbcType.DateTime).Value = createDate; cmd.Parameters.Add("@FailedPasswordAttemptCount", OdbcType.Int).Value = 0; cmd.Parameters.Add("@FailedPasswordAttemptWindowStart", OdbcType.DateTime).Value = createDate; cmd.Parameters.Add("@FailedPasswordAnswerAttemptCount", OdbcType.Int).Value = 0; cmd.Parameters.Add("@FailedPasswordAnswerAttemptWindowStart", OdbcType.DateTime).Value = createDate;
Da in Access für den Primary- Key (User- ID) auch ein OleDb- konformer Datentyp benötigt wird, mit dem die Klasse beispielsweise
die HASH1 - Verschlüsselung handeln kann, muss auch an den jeweiligen Stellen der Klasse in der SQL- Parameterzuweisung der Datentyp
OdbcType.UniqueIdentifier (Odbc) -> zu OleDbType.Guid geändert werden.
In der ACCESS- Datenbank, Eigenschaften der Tabelle ist für den Primary Key, Feldname "PKID" als Datentyp "Zahl" und ->Feldgröße "Replikations-ID" einzustellen.
Anmerkung:
Der Tabellenentwurf, der auch für die manuelle Erstellung der ACCESS- Datenbank mit der Bezeichnung "membership.mdb" verwendet werden kann,
bildet den auskommentierten Teil am Beginn der Odbc Beispiel- Klasse von Microsoft. Ich habe alle Zahlenfelder bis auf die PKID einfach auf "Integer" ohne Nachkommastellen eingestellt.
2. Die fast fertig angepasste OleDb Membership- KLasse "OleDbAnbieterCS.cs" im Verzeichnis App_data testen und Haare raufen :-)
Ich verzichte mal darauf, im einzelnen zu beschreiben, wie die Web.config konkret einzurichten ist, da man hier im MSDN Developer Network alles
Grundsätzliche zum Einrichten und Verwalten der Mitgliedschaft erfährt.
An dieser Stelle vorab nur soviel:
Die Klasse holt sich den Connection- String für die Verbindung zur ACCESS- Datenbank aus dem Abschnitt in der Web.config. Die Datenbank selbst sollte
natürlich nicht mit irgendwelchen ACCESS- internen Benutzerrechtseinstellungen versehen sein und freien Zugriff ermöglichen.
Bei mir funktioniert folgender Connection- String in der Web.config:
<
add name="OleDbServices" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\inetpub\wwwroot\Verzeichnis\Verzeichnis\App_Data\membership.mdb;Persist Security Info=True" />
Wirklich wichtig ist an der Stelle, dass unsere MembershipProvider- Klasse "OleDbMembershipProvider" in der Web.config im Abschnitt <System.Web> bekannt
gemacht wird, indem der vom NET.Framework voreingestellte SQL- Provider für die Formularmitgleidschaft mit remove entfernt (lokal überschrieben) wird:
<
membership defaultProvider="OleDbProvider" userIsOnlineTimeWindow="15">
<providers>
<remove name="AspNetSqlMembershipProvider" />
<add name="OleDbProvider" type="Samples.AspNet.Membership.OleDbMembershipProvider" connectionStringName="OleDbServices" enablePasswordRetrieval="true" enablePasswordReset="true" requiresQuestionAndAnswer="true" writeExceptionToEventLog="true" />
</providers>
</membership>
Dabei muss natürlich wie vorstehend der Namespace "Samples.AspNet.Membership" und der Klassenbezeichner "OleDbMembershipProvider" mit den Namen in der
Klassendatei identisch sein.
BEIM TEST DIE TÜCKE !
Zum Schluss kommt, nachdem alles Startklar für die erste Anmeldung zu sein scheint, das Unerwartete (wie immer) :
Es gibt vom Debugger eine kryptische Fehlermeldung, die auf ein Problem mit den SQL- Statements in unserer
frisierten Klasse hinweist und dieser Fehler ist so tückisch, dass hier nochmal ein Codeausschnitt gezeigt werden muß:
OleDbConnection conn = new OleDbConnection(connectionString); OleDbCommand cmd = new OleDbCommand("UPDATE Users " + " SET Pasword = ?, LastPasswordChangedDate = ? " + " WHERE Username = ? AND ApplicationName = ?", conn); cmd.Parameters.Add("@Pasword", OleDbType.VarChar, 255).Value = EncodePassword(newPwd); cmd.Parameters.Add("@LastPasswordChangedDate", OleDbType.Date).Value = DateTime.Now; cmd.Parameters.Add("@Username", OleDbType.VarChar, 255).Value = username; cmd.Parameters.Add("@ApplicationName", OleDbType.VarChar, 255).Value = pApplicationName;
WICHTIG, abändern!
Ich weiß nicht wieso aber es ist so, dass OleDb in den SQL- Statements für das gleichnamige Datenbankfeld
offenbar nicht mit "SET Password" bzw. bei der Parameterzuweisung mit "@Password" zurecht kommt.
Das Odbc- Beispiel von Microsoft verwendet diese Schreibweise mit dem doppeltem "s" jedoch.
Nachdem ich in der Datenbank das Feld in "Pasword" abgeändert und die SQL- Statements auch durchgeändert habe,
lief der Debugger durch und alles war schön.
Das Gemeine an diesem Bug ist, dass hier offenbar die OleDb- Schnittstelle betroffen ist und die Zusammenarbeit mit
der KLasse verweigert, weil offenbar Password mit ss ein Schlüsselwort zu sein scheint. Ich weiß nicht, ob das vielleicht
bei Verwendung über Odbc auch so ist. Jedenfalls kommt man nicht drauf, weil es keine klare Debugger- Meldung gibt.
Ich habe an das Schlüsselwort- Problem in letzter "Verzweiflung" gedacht und aus Password einfach mal "Pasword" gemacht.
Das wars.
Für nicht ganz schöne Formatierungen bitte ich um Nachsicht, habe mich aber um die Code- Tags diesmal bemüht.
Beste Grüsse