5 Stimmen

WCF + Benutzeranmeldeinformationen

Ich arbeite an einer Silverlight v3-Webanwendung und möchte den Zugriff auf den WCF-Dienst sichern, den ich zum Abrufen meiner Daten verwende. Derzeit funktioniert der WCF-Dienst einwandfrei, aber er erfordert keine Benutzeranmeldeinformationen.

Da ich mit diesem Aspekt von WCF nicht sehr erfahren bin, war meine erste Idee, den Operationen meines Dienstes Parameter für Benutzernamen und Kennwort hinzuzufügen. Das Problem, das ich damit habe, ist, dass dies eine Menge redundanten Code erfordern würde, und die Tatsache, dass der Benutzername und das Kennwort über die Leitung im Klartext übertragen werden würde.

Was ich möchte, ist eine Möglichkeit, die Anmeldeinformationen im Voraus auf der Client-Seite direkt angeben, nachdem ich meine Service-Proxy erstellen (ich bin mit dem Proxy automatisch aus "Add Service Reference" generiert).

Beim Googeln nach einer Lösung für dieses Problem konnte ich nur Lösungen finden, die meiner ersten Idee ähneln (Verwendung von Benutzernamen/Passwort-Parametern). Könnte mir jemand bitte die richtige Richtung weisen?

Gracias.

7voto

blowdart Punkte 53842

Woher kommen diese Benutzernamen und Kennwörter? Wenn Ihre Website bereits die Forms-Authentifizierung implementiert, können Sie die Eingabe der Anmeldedaten umgehen und das Forms-Authentifizierungs-Cookie verwenden. Wenn Ihre Benutzer angemeldet sind, wird das Cookie mit dem Aufruf des Webdienstes übertragen. Um es auf der anderen Seite zu lesen, müssen Sie ein paar Änderungen vornehmen.

Zuerst müssen Sie den ASP.NET-Kompatibilitätsmodus für WCF im Abschnitt system.ServiceModel aktivieren:

<system.serviceModel>  
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 
</system.serviceModel>

Sobald dies geschehen ist, fügen Sie für jede Dienstmethode, die das ASP.NET-Cookie verstehen soll, das Attribut [AspNetCompatibilityRequirements] zu Ihrer Dienstklasse hinzu

[ServiceContract]
[AspNetCompatibilityRequirements(
    RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class ExampleService
{
}

Innerhalb jeder Methode können Sie nun auf das Objekt HttpContext.Current.User.Identity zugreifen, um die Identität des Benutzers zu ermitteln.

Wenn Sie möchten, dass bestimmte Methoden nur von authentifizierten Benutzern aufgerufen werden, können Sie eine PrincipalPermission verwenden.

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Authenticated=true)]
public string Echo()

Wenn Sie den ASP.NET-Rollenprovider verwenden, werden diese ebenfalls ausgefüllt und Sie können dann eine PrincipalPermission für Methoden verwenden, um sie auf Mitglieder einer bestimmten Rolle zu beschränken:

[OperationContract]
[PrincipalPermission(SecurityAction.Demand, Role="Administators")]
public string NukeTheSiteFromOrbit()

Und das funktioniert natürlich auch in Silverlight2.

1voto

marc_s Punkte 701497

Entwickeln Sie nicht Ihr eigenes Programm und fügen Sie keine expliziten Parameter hinzu - das ist in der Tat viel zu viel Arbeit!

Informieren Sie sich über die WCF-Sicherheitsfunktionen - es gibt viele davon! Sie können z. B. die Nachricht absichern und Anmeldeinformationen in die Nachricht einfügen - und das alles sofort, ohne zusätzliche Codierung auf Ihrer Seite!

Lesen Sie diesen hervorragenden Artikel über WCF-Sicherheit von Michele Leroux Bustamante: http://www.devx.com/codemag/Article/33342

In Ihrem Fall würde ich vorschlagen, dass Sie die Nachrichtensicherheit mit Benutzernamen konfigurieren - und zwar auf beiden Seiten:

Server-seitig:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<services>
  <service name="YourService">
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
  </service>
</services>

Und Sie müssen die gleichen Einstellungen auf der Client-Seite vornehmen:

<bindings>
  <basicHttpBinding>
    <binding name="SecuredBasicHttp" >
      <security mode="Message">
        <message clientCredentialType="UserName"/>
      </security>
    </binding>
  </basicHttpBinding>
</bindings>
<client>
    <endpoint address="http://localhost:8000/MyService"
              binding="basicHttpBinding"
              bindingConfiguration="SecuredBasicHttp"
              contract="IYourService" />
</client>

Jetzt sind sich Server und Client über die Sicherheit einig - auf dem Client geben Sie dann den Benutzernamen und das Kennwort an, die Sie wie folgt verwenden:

YourServiceClient client = new YourServiceClient();

client.ClientCredentials.UserName.UserName = "your user name";
client.ClientCredentials.UserName.Password = "top$secret";

Auf der Serverseite müssen Sie einrichten, wie diese Benutzeranmeldeinformationen überprüft werden - in der Regel entweder anhand einer Windows-Domäne (Active Directory) oder anhand des ASP.NET-Mitgliedschaftsanbietermodells. In jedem Fall wird der Aufruf abgelehnt, wenn die Benutzeranmeldeinformationen nicht anhand des von Ihnen definierten Speichers überprüft werden können.

Ich hoffe, das hilft ein bisschen - Sicherheit ist ein großes Thema in WCF und hat viele, viele Optionen - es kann ein bisschen entmutigend sein, aber am Ende macht es normalerweise Sinn! :-)

Marc

0voto

Steve Punkte 11396

Können Sie eine Art Authentifizierungsobjekt übergeben und es auf der Nachrichtenebene mit WCF verschlüsseln. C#-Aspekte ( http://www.postsharp.org/ ) kann dann verwendet werden, um redundante Logik zu vermeiden. Das ist eine sehr saubere Art der Handhabung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X