WCF服务授权模式我正在实现一个安全的WCF服务。使用用户名/密码或Windows凭据进行身份验证。该服务托管在Windows服务进程中。现在,我正试图找出为每个服务操作实施授权的最佳方式。例如,考虑以下方法:publicEntityInfoGetEntityInfo(stringentityId);您可能知道,在WCF中,有一个OperationContext对象,您可以从中检索调用方/客户端传入的安全凭证。现在,当调用该方法的第一行时,身份验证已经完成。但是,如果决定取决于输入数据本身,我们如何执行授权呢?例如,在上面的例子中,假设“admin”用户(其权限等存储在数据库中)被允许获取实体信息,其他用户则不允许……我们在哪里进行授权检查?假设我们将它放在方法的第一行,如下所示:CheckAccessPermission(PermissionType.GetEntity,user,entityId)//用户是从当前的OperationContext中拉出的检查validationentityId(例如检查null/空值等)?换句话说,如果每个方法都应该包含授权检查,这是一个好的模式吗?哪个应该先发生——参数认证还是授权?当授权检查像这样到处都是时,我们如何对WCF服务进行单元测试,并且我们在单元测试中没有OperationContext!?(假设我试图在没有任何WCF设置的情况下直接测试这个服务类实现)。有什么想法吗?问题1,绝对先授权。在获得授权以维护最严格的安全性之前,不得执行任何代码(在您的控制范围内)。上面保罗的例子很棒。对于问题2,您可以通过子类化具体服务实现来处理这个问题。如上所述,真正的业务逻辑是使用抽象的“CheckPermissions”方法作为抽象类实现的。然后创建2个子类,一个供WCF使用,另一个(在未部署的DLL中非常孤立)返回true(或您希望它在单元测试中执行的任何操作)。示例(注意,这些不应该在同一个文件中,甚至不在DLL中!):publicabstractclassMyServiceImpl{publicvoidMyMethod(stringentityId){//继续……}protectedabstractboolCheckPermissions(stringentityId);}publicclassMyServiceUnitTest{privateboolCheckPermissions(stringentityId){returntrue;}}publicclassMyServiceMyAuth{privateboolCheckPermissions(stringentityId){//dosomecustomauthenticationreturntrue,}}然后您的WCF部署使用“MyServiceMyAuth”类,并对另一个进行单元测试。对于问题1,最好先进行授权。这样您就不会将身份验证错误消息泄露给未经授权的用户。顺便说一下,您可能能够连接到WCF对ASP.NET角色提供程序的现成支持,而不是使用自行开发的身份验证方法(我假设您的CheckAccessPermission是什么)。完成此操作后,您将通过OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.IsInRole()执行授权。PrimaryIdentity是一个IPrincipal。关于问题#2,我会使用依赖注入并设置您的服务实现,如下所示:私人IAuthorization_auth;publicEntityInfoGetEntityInfo(stringentityId){_auth.CheckAccessPermission(PermissionType.GetEntity,user,entityId);//获取实体信息}}注意IAuthorization是你要定义的接口。由于您将直接测试服务类型(即不在WCF托管框架内运行),您只需将服务设置为使用允许所有调用的虚拟IAuthorization类型。但是,更好的测试是模拟IAuthorization并测试它是否使用您期望的参数调用。这允许您测试对授权方法的调用以及方法本身是否有效。将授权分离到它自己的类型中还可以让您更轻松地单独测试它是否正确。根据我(虽然有限)的经验,使用DI“模式”可以更好地分离关注点和类型的可测试性,并导致更清晰的界面(这显然值得商榷)。我最喜欢的模拟框架是RhinoMocks,它是免费的并且有一个非常漂亮的界面,但还有很多其他的。如果想深入了解DI,可以参考一些好的入门书和.Netframework:以上就是C#学习教程的全部内容:WCF服务授权模式分享,如果对大家有用还需要深入了解C#学习教程,希望大家多多关注~本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
