(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可以这样写
posted @ 2016-08-30 10:02  IWing  阅读(394)  评论(0编辑  收藏  举报