2010-09-15 15 views
16

Sto lavorando all'autenticazione e all'autorizzazione WCF personalizzate e ho trovato alcuni articoli su UserNamePasswordValidator e ServiceAuthorizationManager.Autenticazione WCF personalizzata con System.ServiceModel.ServiceAuthenticationManager?

Ho trovato anche indizi sull'utilizzo di un System.ServiceModel personalizzato . ServiceAuthenticationManager (dead link), ma msdn non ne parla molto (http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceauthenticationmanager.aspx).

Quindi eccomi: qualcuno sa di più su ServiceAuthenticationManager?

In generale, come si configurerà l'autenticazione WCF personalizzata?

+4

E 'strano, ma c'è ancora sembra che ci sia un sacco di informazioni e campioni per ServiceAuthorizationManager, ma quasi nulla per ServiceAuthenticationManager – Cocowalla

risposta

35

Hai ragione, la documentazione su questo non aiuta affatto.

Il modo in cui ho utilizzato questa classe è il seguente. Eseguire l'override del metodo di autenticazione() a:

  1. Tirare i token di autenticazione (ad esempio nome utente/password) dal messaggio in arrivo
  2. autenticare il token e li usa per creare un oggetto IPrincipal. Questo sarà il principale utilizzato durante l'invocazione dell'operazione di servizio.
  3. aggiungere l'oggetto IPrincipal alla raccolta message.Properties modo che possa essere utilizzato in seguito nella pipeline di elaborazione WCF

Non si può semplicemente impostare il principale filo a questo punto come è cambiato in seguito da WCF .

Il codice nella ServiceAuthenticationManager.Authenticate() metodi sarebbero simile a questo:

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; 
} 

quindi si aggiunge un criterio di autorizzazione personalizzato che

  1. Recupera l'IPrincipal dal messaggio (utilizzando il Raccolta System.ServiceModel.EvaluationContext.Current.IncomingMessageProperties).
  2. spinge l'IPrincipal nella collezione EvaluationContext.Properties
  3. fa affermazioni sulla base del metodo di IPrincipal.IsInRole

() Il codice nella IAuthorizationPolicy() metodo sarebbe simile

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; 
} 

Nella configurazione del comportamento del servizio, è necessario impostare principalPermissionMode = "Custom" in modo che WCF imposti l'IPrincipal come principale sul thread in esecuzione per l'effettiva operazione di richiamo dell'operazione.

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

Grazie, che è stato davvero utile. Saluti :-) – fredlegrain

+0

È possibile aggiungere un'Identità di rivendicazione a ClaimSet in ServiceAuthenticationManager.Autentica() piuttosto che inserire il Principal nelle Proprietà? –

+1

È possibile. Il flusso previsto credo sia che AuthenticationManager convalidi le credenziali e faccia un'entità con le attestazioni che provengono direttamente dal provider di identità (una richiesta di identità sarebbe una di queste), la AuthorizationPolicy trasforma le rivendicazioni e l'AuthorizationManager prende la decisione di autorizzazione. La documentazione su questo è scarsa, quindi è difficile dirlo. Ad ogni modo, ora che WIF è disponibile, il modello è più semplice: o) –

Problemi correlati