visual studio servicio publicar mundo hola extremo encontrado crear c# .net wcf authorization

c# - studio - Patrones de autorización del servicio WCF



servicio wcf c# (3)

Estoy implementando un servicio seguro de WCF. La autenticación se realiza usando nombre de usuario / contraseña o credenciales de Windows. El servicio está alojado en un proceso de servicio de Windows. Ahora, estoy tratando de encontrar la mejor manera de implementar la autorización para cada operación de servicio.

Por ejemplo, considere el siguiente método:

public EntityInfo GetEntityInfo(string entityId);

Como ya sabrá, en WCF, hay un objeto OperationContext desde el que puede recuperar las credenciales de seguridad pasadas por el llamador / cliente. Ahora, la autenticación ya habría terminado cuando se llame a la primera línea del método. Sin embargo, ¿cómo implementamos la autorización si la decisión depende de los datos de entrada en sí? Por ejemplo, en el caso anterior, digamos que los usuarios ''admin'' (cuyos permisos, etc. están almacenados en una base de datos), pueden obtener información de la entidad, y otros usuarios no deberían estar autorizados ... ¿dónde colocamos las verificaciones de autorización?

Digamos que lo ponemos en la primera línea del método así:

CheckAccessPermission(PermissionType.GetEntity, user, entityId) //user is pulled from the current OperationContext

Ahora, hay un par de preguntas:

  1. ¿Validamos el ID de la entidad (por ejemplo, verificar el valor nulo / vacío, etc.) ANTES de la verificación de la autorización o DENTRO de la verificación de la autorización? En otras palabras, si se deben incluir verificaciones de autorización en cada método, ¿es un buen patrón? ¿Qué debería suceder primero - validación o autorización del argumento?

  2. ¿Cómo probamos la unidad de un servicio WCF cuando las verificaciones de autorización están por todas partes así, y no tenemos un OperationContext en la prueba unitaria? (Suponiendo que estoy tratando de probar esta implementación de la clase de servicio directamente sin ninguna de las configuraciones de WCF).

¿Alguna idea, chicos?


Para la pregunta 1, es mejor realizar la autorización primero. De esta forma, no se filtran los mensajes de error de validación a usuarios no autorizados.

Por cierto, en lugar de utilizar un método de autenticación local (que supongo que es su CheckAccessPermission), es posible que pueda conectarse al soporte inmediato de WCF para los proveedores de roles de ASP.NET. Una vez hecho esto, realiza la autorización a través de OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.IsInRole (). PrimaryIdentity es un IPrincipal.


Sobre la pregunta n. ° 2, haría esto usando Dependency Injection y configurando su implementación de servicio de la siguiente manera:

class MyService : IMyService { public MyService() : this(new UserAuthorization()) { } public MyService(IAuthorization auth) { _auth = auth; } private IAuthorization _auth; public EntityInfo GetEntityInfo(string entityId) { _auth.CheckAccessPermission(PermissionType.GetEntity, user, entityId); //Get the entity info } }

Tenga en cuenta que IAuthorization es una interfaz que definiría.

Como va a probar el tipo de servicio directamente (es decir, sin ejecutarlo dentro del marco de alojamiento de WCF), simplemente configure su servicio para usar un tipo de autorización IA ficticia que permita todas las llamadas. Sin embargo, una prueba incluso MEJOR es burlarse de la Autorización IA y probar que se llama cuando y con los parámetros que espera. Esto le permite probar que sus llamadas a los métodos de autorización son válidas, junto con el método en sí.

Separar la autorización en su propio tipo también le permite probar más fácilmente que es correcta de forma aislada. En mi experiencia (aunque limitada), el uso de "patrones" de DI le proporciona una separación mucho mejor de las inquietudes y la capacidad de prueba en sus tipos, así como también una interfaz más limpia (esto obviamente está abierto al debate).

Mi marco preferido de burla es RhinoMocks, que es gratuito y tiene una interfaz muy fluida, pero hay muchos otros por ahí. Si desea obtener más información sobre DI aquí hay algunos buenos iniciadores y .Net frameworks:


Para la pregunta 1, absolutamente haga la autorización primero. Ningún código (dentro de su control) debe ejecutarse antes de la autorización para mantener la seguridad más estricta. El ejemplo anterior de Pablo es excelente.

Para la pregunta 2, puede manejar esto subclasificando la implementación de su servicio concreto. Haga que la verdadera implementación de la lógica de negocios sea una clase abstracta con un método abstracto "CheckPermissions" como menciona arriba. A continuación, cree 2 subclases, una para el uso de WCF y otra (muy aislada en una DLL no desplegada) que devuelve verdadero (o lo que quiera que haga en su prueba de unidad).

Ejemplo (nota, ¡estos no deberían estar en el mismo archivo o incluso en DLL!):

public abstract class MyServiceImpl { public void MyMethod(string entityId) { CheckPermissions(entityId); //move along... } protected abstract bool CheckPermissions(string entityId); } public class MyServiceUnitTest { private bool CheckPermissions(string entityId) { return true; } } public class MyServiceMyAuth { private bool CheckPermissions(string entityId) { //do some custom authentication return true; } }

Entonces su despliegue de WCF usa la clase "MyServiceMyAuth", y usted hace su prueba unitaria contra la otra.