我执行一个安全的WCF服务。认证是通过使用用户名和密码或窗户证书。该服务举办的Windows服务的过程。现在,我正在尝试找出最佳的方式来实施 授权 每个服务操作。

例如,考虑以下方法:

public EntityInfo GetEntityInfo(string entityId);

因为你可能知道,在WCF,有一个OperationContext对象从中可以检索的安全凭证,通过在通过呼叫者/客户。现在,身份验证 就已经完成的时间的第一线的方法。然而,我们如何实施授权如果决定取决于输入数据本身?例如,在上述情况,说'管理'的用户(其权限等,都存储在数据库),被允许获得实体的信息,以及其他用户不应该被允许的...我们在哪里把授权的检查?

说我们把它放在第一线的方法,像这样:

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

现在,有几个问题:

  1. 我们验证entityId(例如检查空/空值等等)之前,授权检查或内部的授权检查?换句话说,如果授权的检查,应包括在每一个方法,这是一个良好的模式?这应该发生的第一说法验证或授权?

  2. 我们怎么单元的测试WCF服务时授权检查所有过这样的地方,我们没有一个OperationContext在该单元的测试!?(假设我试着测试这类服务实施直接而没有任何周转基金设置)。

任何想法,伙计们?

有帮助吗?

解决方案

对于问题1,绝对先做授权。在授权之前,不应执行任何代码(在您的控制范围内)以保持最严格的安全性。上面保罗的例子很棒。

对于问题2,您可以通过继承具体的服务实现来处理这个问题。使真正的业务逻辑实现成为一个带有抽象“CheckPermissions”的抽象类。如上所述的方法。然后创建2个子类,一个用于WCF使用,另一个(在非部署的DLL中非常孤立)返回true(或者您希望它在单元测试中做的任何事情)。

示例(注意,这些不应该在同一个文件中,甚至不应该在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;
    }
}

然后,您的WCF部署使用类“MyServiceMyAuth”,并对另一个进行单元测试。

其他提示

对于问题1,最好先执行授权。这样,您就不会将验证错误消息泄漏回未经授权的用户。

BTW,您可能能够连接到WCF对ASP.NET角色提供程序的开箱即用支持,而不是使用自行开发的身份验证方法(我假设您的CheckAccessPermission是什么)。完成此操作后,您将通过OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.IsInRole()执行授权。 PrimaryIdentity是一个IPrincipal。

关于问题2,我会做这种使用依赖注射和设置你的服务实现这样的事情:

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

注意IAuthorization是一个接口,你会定义。

因为你是要测试的服务类型直接(就是说,没有运行的内部周转基金的托管框架)你只需设置服务使用一个虚拟IAuthorization类型,它允许所有通话。然而,一个更美好的试验是模拟的IAuthorization和测试,它被称为当和与参数。这可以让你的测试,你的电话到授权的方法是有效的,随着方法本身。

分离的授权进入它自己的类型也可以让你更容易地测试,它是正确的,在隔离。在我的(尽管有限)的经验,采用DI"模式"给你极大的更好分离的问题,并测试在您的类型以及导致一个更清洁的接口(这显然是开放的辩论).

我的首选框架是嘲讽 RhinoMocks 这是免费的,并具有非常好的流利口但还有很多其他人那里。如果你想知道更多关于DI这里有一些很好的引物和。净框架:

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top