在系统开发的时候一个老生常谈的权限管理问题,翻阅了很多的网络资料,但是总感觉离实际使用还有一段距离,其实权限控制无非就几个“请求、页面按钮、字段显示”, 对于前端权限就需要配合JS了, 这里主要展示我这些年来一直使用的一个关于权限管理的案例,如果你只是写一个简单的CMS系统,那么下面代码其实拷贝就可以用了,如果是需要进行较大型系统开发就需要进一步封装, 下面是我的思路,写的不好大家勿喷哈,有不同意见的留下一起探讨。

1、在MVC开发时路由中包含了我们所有请求信息(Controller、Action、URL全文),而MVC又提供了过滤器的机制,因此我们将权限管理封装到过滤其中。首先把每个Controller的继承封装一个BaseController,这个Controller基类可以编写一些直接调用的方法,例如Session等。

    /// <summary>
/// 系统基础控制器类
/// </summary>
public abstract class BaseUIController : Controller
{
/// <summary>
/// 页面初始化过程
/// </summary>
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
{
requestContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache);
base.Initialize(requestContext);
} /// <summary>
/// 内容返回
/// </summary>
/// <param name="content">特定内容供JS参考是否含流程定义等动作。</param>
/// <param name="contentType"></param>
/// <param name="contentEncoding"></param>
/// <returns></returns>
protected override ContentResult Content(string content, string contentType, Encoding contentEncoding)
{
return base.Content(content, contentType, contentEncoding);
} /// <summary>
/// 登陆用户ID (Session存储)
/// </summary>
public long LoginedUserID
{
get
{
object UID = Ant.UI.Controls.SessionConfig.GetSession("UID");
if (Session == null || UID == null)
return -;
else
{
return (long)UID;
}
}
set
{
Ant.UI.Controls.SessionConfig.SetSession("UID", value);
}
} /// <summary>
/// 获取URL参数值,返回 NULL 或 值
/// </summary>
/// <param name="keyName">参数名</param>
public string RequestUrlParams(string keyName)
{
if (Array.IndexOf(Request.QueryString.AllKeys, keyName) >= )
return Request.QueryString[keyName].ToString();
else
return null;
}
}

2、这个时候我们编写一个过滤器,在这个过滤器中可以在请求的Controller中获取controller名称和action名称。 有了这两个名称就能定位到具体的页面了,当然在得到页面之前我们可以判断用户是否已经登录。而页面权限页已经用数据库保存起来:A用户或R角色对某一个Controller/Action的页面(这个页面可能是新增信息、修改、删除信息的请求链接)是否有访问权限。

    /// <summary>
/// 用户登录过滤器
/// </summary>
public class UserLoginedFilter : AuthorizeAttribute
{
public string name { get; set; }
/// <summary>
/// 页面授权过程(验证用户登录状态)
/// </summary>
/// <param name="filterContext"></param>
public override void OnAuthorization(AuthorizationContext filterContext)
{
UI.Controllers.BaseUIController _ControllerObj = (UI.Controllers.BaseUIController)filterContext.Controller;
string controllerStr = _ControllerObj.ControllerContext.RouteData.Values["controller"].ToString();
string actionStr = _ControllerObj.ControllerContext.RouteData.Values["action"].ToString(); //用户尚未登陆 或 登陆超时。
if (_ControllerObj.LoginedUserID == -)
{
UserError.LoginError();
}
// 权限验证 根据 Controller 与 Action(这里可以将权限缓存取出来进行用户匹配,如果被拒绝可以抛出异常)
else if ( controllerStr.ToLower() == "admin" && actionStr.ToLower() == "login")
{
throw new HttpException("权限验证。" + _ControllerObj.ControllerContext.Controller.ToString());
} base.OnAuthorization(filterContext);
}
}

3、此时页面调用时就不用在每个Action中编写权限验证代码啦(有些权限验证的源码会在Action上增加过滤器,为了偷懒硬是想方设法把权限封装成直接在Controller类上添加一次过滤器就能完成的实现)

    [UserLoginedFilter]
public class AdminController : UI.Controllers.BaseUIController
{
/// <summary>
/// 登陆(登陆页面不需要权限验证,增加AllowAnonymous特性)
/// </summary>
[AllowAnonymous]
public ActionResult Login(FormCollection form)
{
return View();
} /// <summary>
/// 主界面
/// </summary>
public ActionResult Index()
{
return View();
}
}

上面只是我在系统开发过程中对于权限管理的一个思路,也实实在在的应用到了一些系统中,当然上面这些代码只能勉强判断是否登陆,如果你需要对数据权限、页面权限、字段权限进行管理那么就需要进一步的扩展。如果需要在抛出异常后将异常信息友好的返回给客户端,那你仍然需要在Global中捕获返回状态码以及错误信息。因此我说这只是我的一个思路,路过的朋友给我建议。多谢!

最新文章

  1. Learn ZYNQ (8)
  2. Map的简单语法
  3. Fiddler-006-修改HTTP请求参数
  4. 替代Eval的两种方式
  5. java异常处理一
  6. dedecms织梦二级菜单的实现方法
  7. leetcode String to Integer (atoi) python
  8. Ansible hostvars
  9. R语言结合概率统计的体系分析---数字特征
  10. CentOS 6.2下搭建Web服务器
  11. IntelliJ IDEA创建多模块依赖项目
  12. zabbix_sender用法实例
  13. pyqt------对话框
  14. 集群安装Java环境
  15. 二进制样式的字符串与byte数组互转函数示例
  16. [转]ionic3 实现android版本打包
  17. MySQL分库分表浅谈
  18. Codeforces Round #487 (Div. 2) E. A Trance of Nightfall (矩阵优化)
  19. python_基础语法
  20. APScheduler 浅析

热门文章

  1. WebSocket和Socket
  2. 写给小前端er的nodejs,mongodb后端小攻略~ (windows系统~)
  3. java 基础之 反射技术
  4. python反编译工具
  5. MAC下的mysql忘记密码该怎么办??
  6. C++ 文件流的方式操作文件(一个简单的写入,读取)
  7. 【最小生成树】Bzoj1232 [Usaco2008Nov]安慰奶牛cheer
  8. BZOJ_2631_tree_LCT
  9. 虚拟机console基础环境部署——配置本地YUM源
  10. 使用 NLog 给 Asp.Net Core 做请求监控