2010-09-15 19 views
16

Pracuję nad niestandardowym uwierzytelnianiem i autoryzacją WCF oraz znajduję niektóre artykuły na temat UserNamePasswordValidator i ServiceAuthorizationManager.Niestandardowe uwierzytelnianie WCF za pomocą System.ServiceModel.ServiceAuthenticationManager?

Znalazłem również wskazówki dotyczące korzystania z niestandardowego System.ServiceModel. ServiceAuthenticationManager (martwy link), ale msdn niewiele o tym mówi (http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceauthenticationmanager.aspx).

Więc oto jestem: ktoś wie więcej o ServiceAuthenticationManager?

Ogólnie, jak skonfigurować niestandardowe uwierzytelnianie WCF?

+4

To dziwne, ale wciąż wydaje się być dużo informacji i próbek do ServiceAuthorizationManager, ale prawie nic o ServiceAuthenticationManager – Cocowalla

Odpowiedz

35

Masz rację, dokumentacja na tym nie pomaga.

Sposób w jaki używałem tej klasy jest następujący. Zastąpić metodę do uwierzytelniania():

  1. Pociągnąć znaki uwierzytelniania (na przykład nazwa użytkownika/hasło) z wiadomości przychodzących
  2. uwierzytelnienia żetony i wykorzystać je do utworzenia obiektu IPrincipal. Będzie to główna nazwa używana podczas wywoływania operacji usługi.
  3. Dodaj obiekt IPrincipal do kolekcji message.Properties dzięki czemu może być używany później w rurociągu przetwarzania WCF

Nie można po prostu ustawić głównego wątku w tym momencie, jak to zostanie zmienione później przez WCF .

Kod w ServiceAuthenticationManager.Authenticate() metody wyglądałby mniej więcej tak:

public override ReadOnlyCollection<IAuthorizationPolicy> Authenticate(ReadOnlyCollection<IAuthorizationPolicy> authPolicy, Uri listenUri, ref Message message) 
{ 
    int tokenPosition = message.Headers.FindHeader("Token", "http://customnamespace.org"); 
    string token = message.Headers.GetHeader<string>(tokenPosition); 

    IPrincipal user = new CustomPrincipal(token); 

    message.Properties["Principal"] = user; 

    return authPolicy; 
} 

Następnie dodać politykę autoryzacji zwyczaj, że

  1. pobiera IPrincipal z wiadomości (przy użyciu Kolekcja System.ServiceModel.EvaluationContext.Current.IncomingMessageProperties).
  2. Odkłada IPrincipal do kolekcji EvaluationContext.Properties
  3. Sprawia roszczeń opartych na IPrincipal.IsInRole metoda

() Kod w IAuthorizationPolicy() metoda będzie wyglądać

public bool Evaluate(EvaluationContext evaluationContext, ref object state) 
{ 
    IPrincipal user = OperationContext.Current.IncomingMessageProperties["Principal"] as IPrincipal; 
    evaluationContext.Properties["Principal"] = user; 
    evaluationContext.Properties["Identities"] = new List<IIdentity> { user.Identity }; 

    IList<Claim> roleClaims = this.GetRoleClaims(user); 

    evaluationContext.AddClaimSet(this, new DefaultClaimSet(this.Issuer, roleClaims)); 

    return true; 
} 

W konfiguracji zachowania usługi należy ustawić metodę principalPermissionMode = "Niestandardowa", aby funkcja WCF ustawiła wartość IPrincipal jako główną w wątku wykonawczym dla faktycznego wywołania operacji usługi.

<serviceAuthorization principalPermissionMode="Custom"... 
+1

Dzięki, że był bardzo pomocny. Pozdrawiam :-) – fredlegrain

+0

Czy można dodać tożsamość Roszczenie do ClaimSet w ServiceAuthenticationManager.Authenticate() zamiast umieszczania Principal w Properties? –

+1

Jest to możliwe. Uważam, że zamierzonym przepływem jest to, że AuthenticationManager sprawdza poprawność danych uwierzytelniających i składa zlecenie z roszczeniami pochodzącymi bezpośrednio od dostawcy tożsamości (roszczenie dotyczące tożsamości jest jednym z nich), AuthorizationPolicy przekształca oświadczenia, a AuthorizationManager podejmuje decyzję o autoryzacji. Dokumentacja na ten temat jest skąpa, więc trudno powiedzieć. W każdym razie, teraz, gdy WIF jest dostępny, model jest prostszy: o) –

Powiązane problemy