2010-09-15 13 views
16

Estoy trabajando en la autenticación y autorización personalizadas de WCF y encontré algunos artículos sobre UserNamePasswordValidator y ServiceAuthorizationManager.Autenticación WCF personalizada con System.ServiceModel.ServiceAuthenticationManager?

También encontré pistas sobre el uso de un sistema personalizado System.ServiceModel. ServiceAuthenticationManager (vínculo muerto), pero msdn no dice mucho al respecto (http://msdn.microsoft.com/en-us/library/system.servicemodel.serviceauthenticationmanager.aspx).

Así que aquí estoy: ¿alguien sabe más acerca de ServiceAuthenticationManager?

En general, ¿cómo configurar la autenticación WCF personalizada?

+4

Es raro, pero todavía parece que hay una gran cantidad de información y muestras para ServiceAuthorizationManager, pero casi nada para ServiceAuthenticationManager – Cocowalla

Respuesta

35

Tienes razón, la documentación sobre esto no es de ninguna ayuda.

La forma en que he usado esta clase es la siguiente. Reemplazar el método Authenticate() para:

  1. Tire los tokens de autenticación (por ejemplo, nombre de usuario/contraseña) fuera del mensaje entrante
  2. autenticar el tokens y utilizarlos para crear un objeto IPrincipal. Este será el principal que se usa durante la invocación de la operación del servicio.
  3. añadir el objeto IPrincipal a la colección message.Properties para que pueda ser utilizado más adelante en la tubería de proceso WCF

No se puede establecer la directora hilo en este punto, ya que se cambió más tarde por la WCF .

El código en el ServiceAuthenticationManager.Authenticate() métodos podrían ser algo como esto:

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

Luego se agrega una política de autorización personalizada que

  1. Recupera el IPrincipal del mensaje (utilizando el System.ServiceModel.EvaluationContext.Current.IncomingMessageProperties collection).
  2. empuja el IPrincipal en la colección EvaluationContext.Properties
  3. hace afirmaciones basadas en el método de IPrincipal.IsInRole

() El código en el IAuthorizationPolicy() método se vería

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

En la configuración del comportamiento del servicio, debe establecer principalPermissionMode = "Custom" para que WCF configure el IPrincipal como el principal en el hilo de ejecución para la invocación real de la operación del servicio.

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

Gracias, que fue muy útil. Saludos :-) – fredlegrain

+0

¿Es posible agregar un reclamo de identidad al ClaimSet en ServiceAuthenticationManager?¿Autenticar() en lugar de poner el principal en las propiedades? –

+1

Es posible. El flujo previsto, creo, es que AuthenticationManager valida las credenciales y crea un principal con los reclamos que provienen directamente del proveedor de identidad (un reclamo de identidad sería uno de estos), AuthorizationPolicy transforma los reclamos y AuthorizationManager toma la decisión de autorización. La documentación sobre esto es escasa, por lo que es difícil de decir. De todos modos, ahora que el WIF está disponible, el modelo es más simple: o) –

Cuestiones relacionadas