2009-04-27 12 views
8

Ich versuche, einen WCT-REST-Service verfügbar zu machen und nur Benutzer mit einem gültigen Benutzernamen und Passwort können darauf zugreifen. Der Benutzername und das Passwort werden in einer SQL-Datenbank gespeichert. HierWie übergeben Sie Benutzeranmeldeinformationen vom WebClient an einen WCF-REST-Service?

ist der Servicevertrag:

public interface IDataService 
{ 
    [OperationContract] 
    [WebGet(ResponseFormat = WebMessageFormat.Json)] 
    byte[] GetData(double startTime, double endTime); 
} 

Hier ist die WCF-Konfiguration:

<bindings> 
    <webHttpBinding> 
    <binding name="SecureBinding"> 
     <security mode="Transport"> 
     <transport clientCredentialType="Basic"/> 
     </security> 
    </binding> 
    </webHttpBinding> 
</bindings> 
<behaviors> 
    <serviceBehaviors> 
    <behavior name="DataServiceBehavior"> 
     <serviceMetadata httpGetEnabled="true"/> 
     <serviceCredentials> 
     <userNameAuthentication 
      userNamePasswordValidationMode="Custom" 
      customUserNamePasswordValidatorType= 
       "CustomValidator, WCFHost" /> 
     </serviceCredentials> 
    </behavior> 
    </serviceBehaviors> 
</behaviors> 
<services> 
    <service behaviorConfiguration="DataServiceBehavior" name="DataService"> 
    <endpoint address="" binding="webHttpBinding" 
       bindingConfiguration="SecureBinding" contract="IDataService" /> 
    </service> 
</services> 

ich den Dienst über die WebClient-Klasse innerhalb einer Silverlight-Anwendung zugreifen. Ich bin jedoch nicht in der Lage, herauszufinden, wie die Benutzeranmeldeinformationen an den Dienst übergeben werden. Ich habe verschiedene Werte für client.Credentials ausprobiert, aber keiner von ihnen scheint den Code in meinem benutzerdefinierten Validator auszulösen. Ich erhalte den folgenden Fehler: Die zugrunde liegende Verbindung wurde geschlossen: Beim Senden ist ein unerwarteter Fehler aufgetreten.

Hier ist ein Beispielcode habe ich versucht:

WebClient client = new WebClient(); 
    client.Credentials = new NetworkCredential("name", "password", "domain"); 
    client.OpenReadCompleted += new OpenReadCompletedEventHandler(GetData); 
    client.OpenReadAsync(new Uri(uriString)); 

Wenn ich den Sicherheitsmodus auf Keine setzen, das Ganze funktioniert. Ich habe auch andere clientCredentialType-Werte ausprobiert und keiner von ihnen hat funktioniert. Ich habe auch den WCF-Dienst selbst gehostet, um die Probleme im Zusammenhang mit IIS zu lösen, die versuchen, einen Benutzer zu authentifizieren, bevor der Dienst eine Chance erhält.

Jeder Kommentar zu den zugrunde liegenden Problemen wäre sehr willkommen. Vielen Dank.

Aktualisieren: Dank Mehmet ausgezeichnete Vorschläge. Hier ist die Tracing-Konfiguration, die ich hatte:

Aber ich habe keine Nachricht von meinem Silverlight-Client kommen. Wie für https vs http, habe ich https wie folgt verwendet:

string baseAddress = "https://localhost:6600/"; 
_webServiceHost = new WebServiceHost(typeof(DataServices), 
       new Uri(baseAddress)); 
_webServiceHost.Open(); 

Allerdings habe ich kein SSL-Zertifikat konfiguriert. Ist das das Problem?

+0

Alex, Sie müssen Ihren Dienst für die Verwendung eines sicheren Transportkanals (https) konfigurieren. Die Bindungen auf Client und Server sollten übereinstimmen. Wenn Sie Ihren Service auf IIS hosten, müssen Sie auch SSL für Ihre Site konfigurieren. Möglicherweise müssen Sie auch die Ausführlichkeit in Ihrer Ablaufverfolgung erhöhen, um weitere Details zu erhalten. Sehen Sie sich die Optionen an. Der Dienstkonfigurationseditor erleichtert das Bearbeiten von WCF-Einstellungen. –

+0

Mehmet, danke. Ich habe meinen Dienst "konfiguriert", um https innerhalb des Basisadressen-URI zu verwenden. Für die WebClient-Instanz habe ich dieselbe Adresse mit "https" angegeben (d. H. Https: // localhost: 6600). Sind diese falsch? Wie würdest du sie sonst konfigurieren? Was das Tracing betrifft, habe ich es auf Verbose gesetzt, was alles protokollieren soll. Es hat mehr Sachen protokolliert, aber ich habe nichts vom Silverlight Client gesehen. Vielen Dank. –

+0

Wie wird WCF auf der Client-Seite speziell für die Bindungen konfiguriert? Haben Sie IIS und Ihren Service für SSL konfiguriert? –

Antwort

0

Zuerst möchten Sie möglicherweise WCF Tracing zu Ihrem Dienst hinzufügen, um weitere Details zu erhalten. Zweitens könnte das Problem darin bestehen, dass Sie Benutzeranmeldeinformationen im Klartext senden und WCF die Übertragung von Benutzeranmeldeinformationen im Klartext über ungesicherte Transportkanäle nicht zulässt. Versuchen Sie also entweder, https zu verwenden oder einen Verschlüsselungsalgorithmus anzugeben, um die Benutzeranmeldeinformationen über http zu sichern.

1

Da Sie die Basis-Authentifizierung verwenden, müssen Sie den Benutzernamen und das Kennwort im Anforderungsheader senden. Das Beispiel manuell die Anmeldeinformationen an den Header hinzugefügt wird unten angezeigt:

HttpWebRequest req = (HttpWebRequest)WebRequest.Create(@"https://localhost:6600/MyWCFService/GetData"); 
//Add a header to the request that contains the credentials 
//DO NOT HARDCODE IN PRODUCTION!! Pull credentials real-time from database or other store. 
string svcCredentials = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes("userName" + ":" + "password")); 
req.Headers.Add("Authorization", "Basic " + svcCredentials); 
//Parse the response and do something with it... 
using (WebResponse svcResponse = (HttpWebResponse)req.GetResponse()) 
{ 
    using (StreamReader sr = new StreamReader(svcResponse.GetResponseStream())) 
    { 
    //Sample parses json response; your code here may be different 
    JavaScriptSerializer js = new JavaScriptSerializer(); 
    string jsonTxt = sr.ReadToEnd(); 
    } 
} 
+0

Wie kann ich dies mit 'NTLM' Authentifizierung implementieren? –

+0

Schau dir das an: http://allen-conway-dotnet.blogspot.com/2010/01/how-to-create-aspnet-windows.html oder das http://msdn.microsoft.com/en-us/ Bibliothek/ff648505.aspx für Beispiele zur Windows-Stil-Authentifizierung mit WCF. – atconway

0

Was atconway oben vorgeschlagen scheint richtiger Weg, aber Ihr Service hat Basis 64 String-Daten aus Kopf- und konvertiert zurück zu String lesen und dann authentifizieren . Aber es muss sich bei jedem Anruf authentifizieren.

Ein weiterer Ansatz besteht darin, einen sicheren Schlüssel zu verwenden. und Token

  1. Jeder Kunde hat sicheren Schlüssel, die er auf erste Anforderung sendet, wahrscheinlich in Header.
  2. Sie können Schlüssel wie Schlüssel = MD5Hash (Benutzername + Passwort) generieren;
  3. Als Antwort erhält er Token die, das Token wird dann in jeder Anfrage gesendet. Token kann Guid sein. Jedes Token ist nach x Minuten abgelaufen.
  4. Auf der Serverseite können Sie ein Singleton-Wörterbuch wie Dictionay verwalten, um den Tokenablauf zu überprüfen, wenn die aktuelle Zeit> Ablaufzeit es aus dem Wörterbuch entfernt.
  5. Um Sitzungen zu erneuern, fügen Sie in Ihrem Code die Methode "Sitzung erneuern" hinzu.

Für extream Sicherheit

Haben privates/öffentliches Schlüsselpaar, Client gesamte Post-Daten mit dem öffentlichen Schlüssel verschlüsselt wird, und Sie werden mit privaten Schlüsseln entschlüsseln.

Verwandte Themen