创建一种基于用户角色过滤数据的更好方法

时间:2012-04-02 18:49:29

标签: c# authorization roles

我们有一个服务公开客户端使用的所有数据,所有对象都有接口IAuthorized

需要根据用户凭据过滤到客户端的数据。

流程就像客户端调用服务一样 - >该服务调用从数据库中获取数据的SomeManager类......

这里是AuthorizationManager来过滤数据......

public class SomeManager
    {
        public object[] Foo()
        {
            var data = Repository.GetData();
            return autorizationManager.Filter(data);
        }

        public object[] Foo_Else()
        {
            var data = Repository.GetOtherData();
            return autorizationManager.Filter(data);
        }

    }

你可以看到每个方法都需要过滤,

所以我问你的是:我们可以构建一个基类,用输出数据的某些属性过滤每个方法吗?这很聪明吗? 我们应该这样离开吗?简单的wach方法我们shell调用autorization?

你能想出更好的方法吗?

有些事情是这样的:

public class EngineManager :BaseFilterAutho
{
    [AuthorizationCollection]
    public object[] Foo()
    {
        var data = Dao.GetData();
        return data;  //get filtered
    }
       [SingleCollection]
    public object Foo_Else()
    {
        var data = Dao.GetOtherData().First();
        return data //get filtered
    }

}

1 个答案:

答案 0 :(得分:1)

我参与了一个项目,其中数据是通过用户的授权进行过滤的。使用的方法类似于“AuthorizationManager”方法。这需要编写大量的过滤代码,但它工作正常且易于理解。

还有其他方法,您的想法当然可以实施。你所指的是使用面向方面编程,AOP。这是Java世界中的常见方式,也可以在.Net中使用。 PostSharp是一个使这成为可能的第三方库。我自己从未在一个工作项目中使用过PostSharp,但我现在正在玩它以自己学习AOP。

下面是使用PostSharp实现的一个方面的示例,它将改变方法的返回值以过滤返回的数据。这是一个虚拟的方面,我正在玩PostSharp demo,过滤返回的数据只返回包含字母“S”的那些联系人。

如您所见,此方面要求返回值为IQueryable。我怀疑你总是需要对返回值的数据类型有一些基本的了解,例如:如果你正在使用IQueryable,ICollection,数组或其他东西。

    [Serializable]
    public class CollectionFilterAspect : OnMethodBoundaryAspect
    {
        public override void OnExit(MethodExecutionArgs args)
        {
            base.OnExit(args);
            IQueryable<Contact> retVal = (IQueryable<Contact>)args.ReturnValue;
            args.ReturnValue = from r in retVal where r.LastName.Contains("S") select r;
        }
    }  

要使用此方面,您可以使用建议的语法,在方法上放置一个属性以指示应该对其进行过滤。

[CollectionFilterAspect]
public IQueryable<Contact> GetByName(string value)

虽然这个简短的演示说明这肯定是可能的,但它可能是也可能不是一个好主意。我没有在现实世界的软件中使用它的经验,所以我无法帮助你。