• (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:SqliteLinqTestTestDB""", 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:SqliteLinqTestTestDB""", 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可以这样写
  • 相关阅读:
    Web开发较好用的几个chrome插件
    SQL注入专题
    内存泄露检测之ccmalloc
    ruby method lambda block proc 联系与区别 next break return
    c++构造函数详解
    VIM使用系列之一—配置VIM下编程和代码阅读环境
    一个项目经理的经验总结
    如何改正拖拉的习惯
    PHP开源软件《个人管理系统》希望大家一起来开发
    PHP 开源软件《个人管理系统》——完善登录模块
  • 原文地址:https://www.cnblogs.com/IWings/p/5817185.html
Copyright © 2020-2023  润新知