Nach dem mein Intranet erstellt war und gut lief, brauchte ich eine neue Herausforderung. So beschloss ich den SQL-Server vom Intranet-Server zu trennen und die Kommunikation der beiden Maschinen über Webdienste zu realisieren. Beim großen SQL-Server ist die Möglichkeit gegeben, direkt im SQL-Server einen Webdienst Endpunkt (Webservice-Endpoint) zu erzeugen. Da ich nur über die SQL-Server 2005 Express Edition verfüge, wird deshalb ein IIS auf der Maschine benötigt. Das erstellen der XML-Webdienste ist Dank VWD kein Problem. Der Zugriff auf die Datenbanken ist mittels ADO.NET auch für Anfänger wie mich leicht zu bewerkstelligen. Da auch das bearbeiten der Datenbanken über die Webdienste abgewickelt wird, hätte in dieser Konstellation theoretisch jeder Client in meinem Netzwerk, auch ab und an auch mal Gäste, das Recht und die Möglichkeit die bestehenden Datensätze zu verändern oder gar zu löschen. Da ich mir das jedoch für mich vorbehalten möchte, dachte ich über die Authorisierung der Clients nach. Dabei stieß ich in der MSDN auf den Artikel über die benutzerdefinierter Authentifizierung mit Hilfe von SOAP-Headern. Mir erschien der Ansatz ein HTTP-Modul zur Authentifizierung zu verwenden für mein Vorhaben ungeeignet. Warum sollte ich ein Modul jede Anforderung prüfen lassen, wenn ich doch ganz genau weiß wann eine SOAP-Anforderung an den Server gesendet wird? Vor allem wird in dem Modul der Benutzer-Name und das Passwort aus der aktuellen Web-Seite benötigt. Ich wollte eine transparente Authentifizierung ohne Benutzer-Interaktion. Da die gesamte Kommunikation in einem Intranet stattfindet und in der aufrufenden Seite die Impersonierung verwendet wird, ist ja der Benutzer-Namen des aufrufenden Benutzers bekannt. Also sollte es auch kein Problem sein den Namen zum Webdienst durch zureichen. Wie jedes Objekt das zur Authentifizierung verwendet wird, sollte auch der SOAP-Header nur eine zeitlich begrenzte Gültigkeit haben. Um die im SOAP-Header übertragenen Daten zu validieren, wird aus alle Daten des Header ein Hash-Wert erzeugt und mit übertragen. Die benötigte SOAP-Header Klasse muss also folgende Informationen beinhalten:
- Wann wurde die Anfrage erzeugt
- Wie lange ist sie gültig
- Der Namen des aufrufenden Benutzers
- Sollen Daten in der Datenbank verändert werden
- Einen Hash-Wert zur Validierung der übertragenen Daten
In Code umgesetzt hier die Klasse SoapAuthHeader.cs
using System;
using System.Web.Services.Protocols;
namespace NeBuSa.Web.Services.Protocols
{
/// <summary>
/// Stellt einen SoapHeader zur Authorisierung der
/// Kommunikation mit einem WebService dar.
/// </summary>
/// <remarks>n/a</remarks>
[Serializable]
public sealed class SoapAuthHeader : SoapHeader
{
/// <summary>
/// Initialisert eine neue Instanz der SoapAuthHeader-Klasse.
/// </summary>
/// <remarks>n/a</remarks>
public SoapAuthHeader()
{
}
/// <summary>
/// Der Zeitpunkt, an dem die Anforderung erstellt wurde.
/// </summary>
/// <remarks>n/a</remarks>
public DateTime Created;
/// <summary>
/// Die Gültigkeitsdauer der Anforderung.
/// </summary>
/// <remarks>n/a</remarks>
public long Expires;
/// <summary>
/// Der Name des Benutzers, der die Anforderung ausführt.
/// </summary>
/// <remarks>n/a</remarks>
public string UserName;
/// <summary>
/// Gibt an, ob ein DataSet bearbeitet werden soll.
/// </summary>
/// <remarks>n/a</remarks>
public bool IsEditMode;
/// <summary>
/// Ein Hash-Wert zur Validierung der Übertragenen
/// Daten im SoapHeader.
/// </summary>
/// <remarks>Der Hash wird nur als Byte-Array akzeptiert
/// und nicht als String serialisiert.</remarks>
public byte[] HashValue;
}
}Der SOAP-Header ist erstellt. In den nächsten Einträgen wird die Verwendung der erstellten Klasse gezeigt.
Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war, bitte "kicken" sie ihn.
