Sie sind hier: Weblog

Delegations-Szenarien (ActAs) mit WCF 4.5 und WIF 4.5

Foto ,
14.07.2012 21:03:00

.NET 4.5 wird unter anderem auch die bis dato separat zu installierende Windows Identity Foundation (WIF) beinhalten. Daneben wird Visual Studio 2012 auch direkt, wie Vittorio Bertocci unter [1] schreibt, Unterstützung für WIF 4.5 bieten. Diese Unterstützung kommt in Form einer Visual-Studio-Erweiterung und steht bereits für den aktuellen RC zur Verfügung. Im Rahmen dessen wird ein einfacher Konfigurationsdialog geboten, mit dem ein vorliegendes WCF- oder auch ASP.NET-Projekt für den Einsatz mit WIF konfiguriert werden kann. Mit von der Partie ist auch ein einfacher STS, welcher ohne Benutzerinteraktion ein Token ausstellt. Der Inhalt dieses Tokens (= die auszustellenden Claims) kann ebenfalls über den zuvor erwähnten Konfigurationsdialog festgelegt werden.

Delegations-Szenarien werden von diesem STS jedoch nicht unterstützt, sodass man hierfür auf einen „richtigen“ STS (z. B. ADFS) oder auf einen für Testzwecke selbst entwickelten STS zurückgreifen muss. Einen solchen findet man zum Beispiel in der aktuellen Version des Identity Developer Training Kits [2].

Im Zuge eines Delegations-Szenarios  tauscht ein Service jenes Token, mit dem sich der Aufrufer authentifiziert hat, gegen ein weiteres. Mit dem so erhaltenen zweiten Token kann der Service in weiterer Folge im Namen des eigentlichen Aufrufers auf einen weiteren Service zugreifen. Indem im Zuge dessen das ursprüngliche Token präsentiert wird, zeigt der Service der STS, dass er gerade im Auftrag des jeweiligen Aufrufers agiert. Damit dies möglich ist, muss der Entwickler den Service anweisen, das ursprüngliche Token aufzubewahren. Dazu legt er, wie im nachfolgenden Listing gezeigt, die Eigenschaft saveBootstrapContext innerhalb der identityConfiguration im Konfigurationsabschnitt system.identityModel auf true fest.

<system.identityModel>
    <identityConfiguration saveBootstrapContext="true">
        […]
    </identityConfiguration>
</system.identityModel>

Innerhalb der Service-Implementierung bringt er in weiterer Folge den BootstrapContext in Erfahrung. Wie das nachfolgende Listing demonstriert, beinhaltet dieser das ursprüngliche Token.

var claimsPrincipal = OperationContext.Current.ClaimsPrincipal;
var bootstrapContext = claimsPrincipal.Identities.First().BootstrapContext as BootstrapContext;
var bootstrapToken = bootstrapContext.SecurityToken;

Unter Angabe dieses Tokens kann, wie nachfolgend demonstriert, ein weiterer Service aufgerufen werden. Dabei ist zu beachten, dass sich WCF im betrachteten Fall selber, ohne Zutun der Anwendung, beim in der Konfiguration hinterlegtem STS unter Angabe des angegebenen Tokens, ein weiteres Token holt und sich mit diesem beim aufgerufenen Service authentifiziert. Daneben geht das hier abgebildete Listing davon aus, dass für den zu rufende Service bereits eine Service-Referenz (Dienstverweis) erstellt wurde.

const string clientEndpointName = "WS2007FederationHttpBinding_IFlugBuchungsService";

using (var cf = new ChannelFactory<IFlugBuchungsService>(clientEndpointName))
{
 var proxy = cf.CreateChannelWithActAsToken(bootstrapToken);
 var result = proxy.IsAvailable(flightNumber, date);
 ((IDisposable)proxy).Dispose();
 return result;
}

Der auf diese Weise gerufene Service erkennt nun, dass der Aufruf im Namen des ursprünglichen Benutzers stattfindet: Ein Zugriff auf die Eigenschaft Identity.Name fördert dessen Namen zu Tage. Dem Service bleibt es in diesem Fall jedoch nicht verborgen, dass jemand anders im Namen dieses Benutzers auftritt. Den Name dieses Users ermittelt er über p.Identities.First().Actor.Name. Dieser entspricht jenem Benutzernamen, mit dem sich der zuerst aufgerufene Service bei der STS angemeldet hat.

var p = OperationContext.Current.ClaimsPrincipal;
var originalCaller = p.Identity.Name;
var actor = p.Identities.First().Actor.Name;

Möchte der Entwickler verhindern, dass der Service diesen Umstand bemerkt, ist zur Angabe des Bootstrap-Tokens beim Aufruf dieses Services an der Stelle von CreateChannelWithActAsToken die Methode CreateChannelWithOnBehalfOfToken heranzuziehen.

[1] http://blogs.msdn.com/b/vbertocci/archive/2012/03/15/windows-identity-foundation-in-the-net-framework-4-5-beta-tools-samples-claims-everywhere.aspx

[2] http://www.microsoft.com/en-us/download/details.aspx?id=14347