MVC网站开发之权限管理篇

一、前言

刚到公司没多长时间就开始接触MVC到现在不能说懂了,只能说到达会用这个层次吧,感觉MVC用来写Web还是很强大的,层次清晰。

今天我来写写关于权限管理这一块,自我感觉网站的权限主要分为菜单权限和角色权限,首先说角色权限,比较简单不同角色可以看到不同页面这就是角色权限,菜单权限也可以说是操作权限,就是具体到某一个按钮,或某一个下拉框的查看权限或使用权限。

二、角色权限

1.用户角色

首先来角色权限,每个用户有着多样不同的角色,一对多的关系。

2.菜单管理

在菜单管理中我们就可以这样管理,某一菜单,那一角色可以看到就打上√这样比较容易控制。

3.数据库

再来看数据库中,要有角色的表以及用户与角色关系表。

再就是角色与菜单的关系表,其中PermissionIDs字段为操作权限以|隔开。

4.用户登录

当用户登录时我们就可以根据登陆人的ID取到他的所有角色存到Session中,并根据登录人查出相应的菜单。

//角色基本信息
   SqlHelperParameter sqlHelperParameterRole = new SqlHelperParameter();
   sqlHelperParameterRole.Add("UserId", dtUserRow["UserId"].ToString());
   DataTable dtRole = SqlHelper.ExecuteDataTable(@"
   select
   Sys_Roles.RoleId,
   Sys_Roles.RoleName,
   Sys_Roles.Weight
   from (
    select UserId,RoleId from Sys_UsersInRoles
    where UserId =@UserId
   ) as a left join Sys_Roles on a.RoleId = Sys_Roles.RoleId", sqlHelperParameterRole);
   int dtRoleCount = dtRole.Rows.Count;
   RoleWeightMax = int.MaxValue;
   for (int i = 0; i < dtRoleCount; i++)
   {
    RolesSession rs = new RolesSession();
    rs.RoleID = Guid.Parse(dtRole.Rows[i]["RoleId"].ToString());
    rs.RoleName = dtRole.Rows[i]["RoleName"].ToString();
    rs.Weight = Convert.ToInt32(dtRole.Rows[i]["Weight"]);
    if (RoleWeightMax > rs.Weight)
    {
     RoleWeightMax = rs.Weight;
    }
    RoleList.Add(rs);
   }
public class RolesSession
 {
  public Guid RoleID { get; set; }
  public string RoleName { get; set; }
  //权重
  public int Weight { get; set; }
 }

前台代码:

 <div data-options="region:'west',split:true" title="导航菜单" style="width: 200px; padding1: 1px;
 overflow: hidden;" id="left_nav">
 <div class="easyui-accordion" data-options="fit:true,border:false">
  @H9C.PMS.BLL.LogOn.MenuList.GetMenu(ViewBag.UserName)
 </div>
</div>

控制器:

public static MvcHtmlString GetMenu(string userName)
  {
   Menu menu = new Menu();
   MenuStructure ms = menu.GetMenuListStructure(userName);
   if (ms != null)
   {
    ms.Children.Remove(ms.Children.FirstOrDefault(o => o.ModelCode == "0" && o.ParentID == "0"));
   }
   return new MvcHtmlString(MenuNav("0", ms));
  }

  private static string MenuNav(string menuCode, MenuStructure menuStruc)
  {
   if (menuStruc == null)
   {
    return "<div>没有可用菜单</div>";
   }
   List<MenuStructure> list = menuStruc.Children.Where(m => m.ParentID == menuCode).ToList();
   StringBuilder sbMenu = new StringBuilder();

   foreach (var item in list)
   {
    if (item.ParentID == "0")
    {
     sbMenu.Append("<div title=\"" + item.Title + "\" style=\"overflow: auto;\">");
     sbMenu.Append("<ul id=\"menu" + item.ParentID + "\" class=\"easyui-tree\" animate=\"true\" dnd=\"true\">");
     sbMenu.Append("<li>");

    }
    else
    {
     sbMenu.Append("<ul id=\"menu" + item.ParentID + "\" class=\"easyui-tree\" animate=\"true\" dnd=\"true\">");
     if (item.Children.Count == 0)
     {
      sbMenu.Append("<li>");
     }
     else
     {
      sbMenu.Append("<li state=\"closed\">");
     }
    }

    sbMenu.Append("<span>");

    if (item.Url == "/")
    {
     sbMenu.Append("<a class=\"e-submenu\" href=\"javascript:void(0);\" title=\"" + item.Title + "\" >");
    }
    else
    {
     string tabsIcon = "14";
     if (!string.IsNullOrWhiteSpace(item.Icon))
     {
      tabsIcon = item.Icon.Replace("/Content/images/", "").Replace(".png", "");
     }
     sbMenu.Append("<a class=\"e-submenu\" href=\"#\" onclick=\"addTab('" + item.Url + "','" + item.Title + "')\" >");
     sbMenu.Append("<img src=\"" + item.Icon + "\" >");
    }

    sbMenu.Append("" + item.Title + "");
    sbMenu.Append("</a></span>");
    if (IsExistParent(item.ModelCode, item))
    {
     sbMenu.Append(MenuNav(item.ModelCode, item));
    }
    sbMenu.Append("</li>");
    sbMenu.Append("</ul>");

    if (item.ParentID == "0")
    {
     sbMenu.Append("</div>");
    }

   }
   return sbMenu.ToString();
  }

  private static bool IsExistParent(string modelCode, MenuStructure menuModels)
  {
   var query = menuModels.Children.FirstOrDefault(m => m.ParentID == modelCode);
   if (query == null)
   {
    return false;
   }
   return true;
  }

菜单类:

public class MenuStructure
 {
  public string ModelCode;
  public string Title;
  public string Icon;
  public string Url;
  public string ParentID;
  public List<MenuStructure> Children = new List<MenuStructure>();
 }

其中GetMenuListStructure()方法就是根据用户名获取菜单列表结构,我这里用户名在数据库中是唯一的,在这里注意一点比较麻烦的是根据类可以看出菜单是有父菜单子菜单的所以方法中需要有两个循环去添加。

三、菜单权限
也就是操作权限,比如某一按钮的操作权限。首先我们把所有关于按钮的操作权限存放到一个类中,(有更好的方法请向我推荐谢谢)

public class Menus
 {
  public static int gongdan = 503000000;//任务工单
 }

然后我们需要操作权限的按钮所在的页面的Controllers(加载页面)中存到ViewBag里,如下:

public ActionResult Index()
  {H9C.PMS.BLL.RBAC.Permission pm = new BLL.RBAC.Permission();
ViewBag.IsReportPlan = pm.IsRoleHavePermissions(Roles.Shigongduizhang, Menus.gongdan, base.UserSessionModel, Menus.GongdanReportPlanByShiGongTeamer); //上报施工计划

   return View();
  }
/// <summary>
  /// 判断某权限是否在获取某角色权限的列表中
  /// </summary>
  /// <param name="roleId"></param>
  /// <param name="modelCode"></param>
  /// <param name="userSessionModel"></param>
  /// <param name="permissionCode"></param>
  /// <returns></returns>
  public bool IsRoleHavePermissions(Guid roleId, int modelCode, UserSessionModel userSessionModel, int permissionCode)
  {
   List<PermissionModel> permissionModelList = this.GetRolePermissionList(roleId, modelCode, userSessionModel);
   if (permissionModelList == null)
   {
    return false;
   }
   foreach (var o in permissionModelList)
   {
    if (o.PCode == permissionCode)
    {
     return true;
    }
   }
   return false;
  }
/// <summary>
  /// 获取某角色权限的列表
  /// </summary>
  /// <param name="roleId"></param>
  /// <param name="modelCode"></param>
  /// <param name="userSessionModel"></param>
  /// <returns></returns>
  public List<PermissionModel> GetRolePermissionList(Guid roleId, int modelCode, UserSessionModel userSessionModel)
  {
   foreach (var o in userSessionModel.RoleList)
   {
    if (o.RoleID == roleId)
    {
     List<Model.RBAC.PermissionModel> permissionList = this.PermissionList(roleId, modelCode);
     return permissionList;
    }
   }
   return null;
  }
/// <summary>
  /// 获取某菜单某角色下具有的权限
  /// </summary>
  /// <param name="modelId"></param>
  /// <param name="menuId"></param>
  /// <returns></returns>
  public List<PermissionModel> PermissionList(Guid roleId, int menuId)
  {
   List<PermissionModel> pmList = new List<PermissionModel>();
   using (RBACContext connEF = new RBACContext())
   {
    Sys_Role_Model_Permissions srmp = connEF.Sys_Role_Model_Permissions.FirstOrDefault(o => o.ModelID == menuId && o.RoleId == roleId);
    if (srmp != null)
    {
     string permissions = srmp.PermissionIDs;
     if (!string.IsNullOrWhiteSpace(permissions))
     {
      string[] pids = permissions.Split(new char[] { '|' });
      for (int i = 0; i < pids.Length; i++)
      {
       if (!string.IsNullOrWhiteSpace(pids[i]))
       {
        pmList.Add(new PermissionModel() {
         ModelCode = menuId,
         PCode = Convert.ToInt32(pids[i]),
         PName =""
        });
       }
      }
     }
    }
   }
   return pmList;
  }

最后一个方法中运用到了EF根据菜单以及角色获取某菜单某角色下具有的权限
前台就非常简单的:

@if (ViewBag.IsReportPlan == true)
  {
   @:  
    <a href="#" class="easyui-linkbutton l-btn"
     iconcls="icon-add">按钮</a>
  }

四、尾声

总结一下,就是首先要有一个菜单管理的模块,它不但可以管理菜单还可以管理菜单中的权限以及每个角色关于菜单的权限,然后就是后台的控制,上面权限Model中存的权重,指的是每一角色都有权重,每一个用户都有他的最大权重,根据这个权重我们就可以做很多条件的控制,简单的说也是为了方便吧。
第一篇技术文档,文笔还需要多锻炼,以后会试着多写博文,不会写文档的码农不是好程序员。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Win2008 R2中IIS7.5配置完网站权限不足问题的解决方法

    Windows Server 2008 R2中IIS7.5配置完网站权限不足问题的解决办法: 常见问题: HTTP 错误 500.0 - Internal Server Error无法显示页面,因为发生内部服务器错误. 模块 IsapiModule 通知 ExecuteRequestHandler 处理程序 AboMapperCustom-20607 错误代码 0x800700c1 请求的 URL http://localhost:80/index.php 物理路径 D:\wwwroot\777

  • 如何对ASP.NET网站实现静态化

    ASP .NET技术实现的页面的扩展名为 .aspx,aspx是目前非常流行的一种动态网页格式.动态网页的一个特点是信息交互.更新及时,页面文件少,开发速度快.但是它的一个严重问题是在访问量比较大,而服务器的配置和资源比较有限的情况下,每次访问可能都会频繁的处理程序逻辑.读写数据库等等,降低服务器的性能. 工具/原料 asp.net 静态化方法一: 重写每个页面需要静态化的动态页面.cs文件的 Render()方法,如下图所示.注意红框处,红框处的参数表示要生成静态页面的名字.该方法实现简单,但

  • IIS7/IIS7.5/IIS8网站目录执行权限设置方法(与IIS6不同)

    在IIS6.0中,对于站点每个文件夹,我们都可以在其属性对话框中将执行权限设置为无,当程序对文件夹有写入权限时,这个设置非常有用,它能防止用户上传脚本文件(.asp,.aspx)到服务器并运行: IIS7也有这样的功能,但设置方法不太一样,步骤如下: IIS7/IIS7.5中目录执行权限的设置方法 我们在建站的时候,通常有些目录必须给写入权限,这个时候这些目录就很可能被人写入脚本文件,为了将安全性维护得更好,我们可以关闭这些有写入权限的目录的脚本执行权限.IIS6的时候,我们很容易找到关闭的地方

  • vs2010制作简单的asp.net网站

    直入主题: 打开visual studio 2010程序开发软件 单击菜单栏的文件,依次选新建->网站->ASP.NET空网站,这里我们选择空网站,利于今后DIY自己的网站,最好什么从头来,便于对各类架构的理解(若是选择ASP.NET网站也行,只是里面已经集成了一些东西) 这里我们默认解决方案的名称为WebSite1,单击确定后进入网站的代码页面,在右边的解决方案资源管理器里只有一个web.config文件,这个文件用于对网站进行全局化的设置 web.config其实是一个xml文档,里面有很

  • ASP.NET MVC5网站开发管理列表、回复及删除(十三)

    一.管理列表 跟上次我的列表相似,直接贴代码了. 首先打开Consultation控制器,添加ManageList方法 /// <summary> /// 咨询管理 /// </summary> /// <returns></returns> public ActionResult ManageList() { return View(); } 添加返回json数据的ManageJsonList public JsonResult ManageJsonLis

  • ASP.NET MVC5网站开发之登录、验证和注销管理员篇1(六)

    上次业务逻辑和展示层的架构都写了,可以开始进行具体功能的实现,这次先实现管理员的登录.验证和注销功能. 一.业务逻辑层1.实现256散列加密方法. Ninesky.Core[右键]-> 添加->文件夹,输入文件夹名General. General文件夹[右键]->添加->类,输入类名Security. 引用System.Security.Cryptography命名空间(1),并实现SHA256静态加密方法. 2.Administrator模型类 Ninesky.Core[右键]-

  • Apache Wind2003 配置网站目录权限小结

    非常简单的权限设置,就是访问网站时会弹出用户名和密码,通过身份验证后可以正常浏览,如下图. 在Apache和Windows2003中配置起来也非常方便,主要参考了Apche的手册 1.建立密码文件 Apache在其安装目录的bin子目录中提供了htpasswd工具,用于建立密码文件: 复制代码 代码如下: htpasswd -b -c -m -d -s c:\password.txt username password 其中-m -d -s都是加密的方式,具体见参考手册 2.启用认证 其中方式有

  • IIS PHP环境Temp文件夹的权限问题引起的网站故障

    前几天不知为何,服务器抽风严重- 服务器非常慢,把WINDOWS2003重启了,结果连不上服务器.结果悲剧的去了机房. 查找不出什么问题,GHOST恢复系统. 几天后回去又装了个新站上去.再过两天后,问题又出现了. 排查过程 检查网页服务器,病毒,木马?是否被入侵? 检查数据库服务器,CPU,内存,网络一切正常,相应的端口也做了 IP 限制,只允许网页服务器访问,查看日志文件也没有异常情况 检查其余的 .Net 网站,速度正常,没有任何问题 检查其余的 Php 网站,架构方法一样,也没有任何问题

  • win2003 IIS虚拟主机网站防木马、权限设置、安全配置整理

    一.系统的安装 1.按照Windows2003安装光盘的提示安装,默认情况下2003没有把IIS6.0安装在系统里面. 2.IIS6.0的安装 以下为引用的内容: 开始菜单->控制面板->添加或删除程序->添加/删除Windows组件 应用程序 ---ASP.NET(可选) |--启用网络 COM 访问(必选) |--Internet 信息服务(IIS)---Internet 信息服务管理器(必选) |--公用文件(必选) |--万维网服务---Active Server pages(必

  • ASP.NET MVC5网站开发之实现数据存储层功能(三)

    数据存储层在项目Ninesky.DataLibrary中实现,整个项目只有一个类Repository. Repository中实现增删改查询等方法供业务逻辑层调用,主要功能如下图: 具体步骤 一.添加实体框架的引用 1.打开解决方案,选择项目Ninesky.DataLibrary,在引用上右键,选择管理NuGet程序包. 在NuGet包管理器中的浏览标签中点击EntityFramework,点击右侧栏的安装按钮. 在搜索框输入EntityFramework.zh-Hans,安装假体中文资源包.

随机推荐