(Entity framework 应用篇)把权限判断封装在数据库访问层

这里,我只是以一个例子,说一下简单权限控制,通过这个例子,大家可以设计庞大的权限管理层,把权限控制封装到数据库访问层,这样程序员就不用再写权限判断的代码了

首先,先看看我数据库DBContext的定义

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace WebApplication1
{
public class SysDB:Test.DB.TestDB
{
public SysDB()
: base(@"data source=""F:\SqliteLinqTest\TestDB""", EntityDB.DatabaseType.Sqlite)
{
} }
}

程序员读取UserInfo表,代码是这样

            var db = new SysDB();
var datasource = db.UserInfo.ToArray();

现在,有这样的需求,当前登录用户如果是admin,那么可以读取UserInfo所有字段的值,否则,只能读取id、UserName这两个字段值,并且不能显示属于财务部的user

通常,如果没有权限控制层,程序员需要这样写代码

            var db = new SysDB();
IQueryable<Test.UserInfo> query;
if (CurrentUserName == "admin")
{
query = db.UserInfo;
}
else
{
query = from m in db.UserInfo
where db.Department.Any(p=>p.Name == "财务部" && p.id == m.DepartmentID) == false
select new Test.UserInfo
{
id = m.id,
UserName = m.UserName
};
}
var datasource = query.ToArray();

如果每个页面,甚至每个控件绑定数据的时候,都需要程序员这样写代码做过滤,首先,累死程序员,其次,程序员如果忘记做判断,系统就存在了权限漏洞

现在,我就要把这条规则,封装到数据库访问层,我只需要在DBContext里面做一下重载

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace WebApplication1
{
public class SysDB:Test.DB.TestDB
{
public SysDB()
: base(@"data source=""F:\SqliteLinqTest\TestDB""", EntityDB.DatabaseType.Sqlite)
{
} public override IQueryable<Test.UserInfo> UserInfo
{
get
{
IQueryable<Test.UserInfo> query;
if (Helper.CurrentUserName == "admin")
{
query = base.UserInfo;
}
else
{
query = from m in base.UserInfo
where this.Department.Any(p => p.Name == "财务部" && p.id == m.DepartmentID) == false
select new Test.UserInfo
{
id = m.id,
UserName = m.UserName
};
} return query;
}
}
}
}

OK,封装完毕了,以后,程序员读取UserInfo表,代码还是这样就可以了

            var db = new SysDB();
var datasource = db.UserInfo.ToArray();

而且,不管程序员加任何的where条件,都不会读出属于财务部的user数据,真正做到把权限封死在数据库访问层了

其次,像我前面文章里面提到的那些支持Entity对象的控件,如EntityGridView、TextBoxList等自动绑定数据的控件,由于它们底层也是访问DBContext对象,所以也是受到这个权限的约束

注意:像下面这种写法

                    query = from m in base.UserInfo
where this.Department.Any(p => p.Name == "财务部" && p.id == m.DepartmentID) == false
select new Test.UserInfo
{
id = m.id,
UserName = m.UserName
};
select new Test.UserInfo 这样的写法,在标准的Entity Framework 6 里面是报错的,因为new的类型不能和表对象的类型相同,这种写法,只有在我前面文章介绍的Mr.E生成的数据库dll可以这样写
上一篇:Entity Framework 泛型使用


下一篇:VBS基础篇 - 杂项 - Sendkeys