简述
本文转自http://yuangang.cnblogs.com并加以整理。 今天我们来写一个控制器基类 主要做登录用户、权限认证、日志记录等工作
索引
Asp.net MVC项目系列教程
项目开始
一、在Controllers文件夹下新建一个控制器BaseController
用于控制器基类,主要做登录用户、权限认证、日志记录等工作
二、声明公共变量和容器
变量主要用于我们查询分页的时候用户传递关键字、页码和分页条数
这个用户容器 主要是用户后台用户的一些操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #region 公用变量
public string Keywords { get; set; }
public int Page { get; set; }
public int Pagesize { get; set; }
public IUserManage UserManage = Spring.Context.Support.ContextRegistry.GetContext().GetObject("Service.User") as IUserManage; #endregion
|
三、获取当前用户对象
从Sesssion中获取用户对象,Session过期后 通过 Cookies重新获取用户对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
public Account CurrentUser { get { if (SessionHelper.GetSession("CurrentUser") != null) { return SessionHelper.GetSession("CurrentUser") as Account; } var account = UserManage.GetAccountByCookie(); SessionHelper.SetSession("CurrentUser", account); return account; } }
|
四、重写OnActionExecuting方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| protected override void OnActionExecuting(ActionExecutingContext filterContext) { if (filterContext.HttpContext.Session == null || this.CurrentUser == null) { filterContext.HttpContext.Response.Write( " <script type='text/javascript'> alert('~登录已过期,请重新登录');window.top.location='/'; </script>"); filterContext.RequestContext.HttpContext.Response.End(); filterContext.Result = new EmptyResult(); return; }
#region 公共Get变量 string p = filterContext.HttpContext.Request["page"]; Page = string.IsNullOrEmpty(p) ? 1 : int.Parse(p);
string search = filterContext.HttpContext.Request.QueryString["search"]; if (!string.IsNullOrEmpty(search)) { Keywords = search; } string size = filterContext.HttpContext.Request.QueryString["example_length"]; if (!string.IsNullOrEmpty(size) && System.Text.RegularExpressions.Regex.IsMatch(size.ToString(), @"^\d+$")) { Pagesize = int.Parse(size.ToString()); } else { Pagesize = 10; } #endregion
}
|
五、模块权限验证功能
- 根据模块别名验证对应模块
- 根据模块操作Action验证是否可操作按钮。
如果用户对相应的模块没有相应的操作权限(添加、修改、删除、审核、发布等等,包含自定义操作类型),我们拒绝执行。网站的权限判断是非常普遍的需求,只要自定义一个类继承自AuthorizeAttribute或者实现IAuthorizeFilter,重写相关的判断逻辑就可以了。
原作者在basecontroller下面新建一个权限验证类UserAuthorizeAttribute,继承自AuthorizeAttribute。你也可以在合适的位置单独创建文件,会更好。
添加一个自定义的Attribute,通过AttributeUsage的Attribute来限定Attribute所施加的元素的类型。作为参数的AttributeTarges的值允许通过“或”操作来进行多个值得组合,如果你没有指定参数,那么默认参数就是All 。
AttributeUsage除了继承Attribute的方法和属性之外,还定义了以下三个属性:
- AllowMultiple: 表示是否可以对一个程序元素施加多个Attribute
- Inherited: 表示是否施加的Attribute 可以被派生类继承或者重载。
- ValidOn: 指明Attribute可以被施加的元素的类型。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false)] public class UserAuthorizeAttribute : AuthorizeAttribute { #region 字段和属性 public string ModuleAlias { get; set; } public string OperationAction { get; set; } private string Sign { get; set; }
public BaseController baseController = new BaseController();
#endregion
public override void OnAuthorization(AuthorizationContext filterContext) { if (string.IsNullOrEmpty(ModuleAlias)) { filterContext.HttpContext.Response.Write(" <script type='text/javascript'> alert('^您没有访问该页面的权限!'); </script>"); filterContext.RequestContext.HttpContext.Response.End(); filterContext.Result = new EmptyResult(); return; }
if (baseController.CurrentUser == null) { filterContext.HttpContext.Response.Write(" <script type='text/javascript'> alert('^登录已过期,请重新登录!');window.top.location='/'; </script>"); filterContext.RequestContext.HttpContext.Response.End(); filterContext.Result = new EmptyResult(); return; }
string alias = ModuleAlias;
#region 配置Sign调取控制器标识 Sign = filterContext.RequestContext.HttpContext.Request.QueryString["sign"]; if (!string.IsNullOrEmpty(Sign)) { if (("," + ModuleAlias.ToLower()).Contains("," + Sign.ToLower())) { alias = Sign; filterContext.Controller.ViewData["Sign"] = Sign; } } #endregion
int moduleId = baseController.CurrentUser.Modules.Where(p => p.ALIAS.ToLower() == alias.ToLower()).Select(p => p.ID).FirstOrDefault(); bool _blAllowed = IsAllowed(baseController.CurrentUser, moduleId, OperationAction); if (!_blAllowed) { filterContext.HttpContext.Response.Write(" <script type='text/javascript'> alert('您没有访问当前页面的权限!');</script>"); filterContext.RequestContext.HttpContext.Response.End(); filterContext.Result = new EmptyResult(); return; }
filterContext.Controller.ViewData["PermissionList"] = GetPermissByJson(baseController.CurrentUser, moduleId); }
private string GetPermissByJson(Account account, int moduleId) { var _varPerListThisModule = account.Permissions.Where(p => p.MODULEID == moduleId).Select(R => new { R.PERVALUE }).ToList(); return Common.JsonHelper.JsonConverter.Serialize(_varPerListThisModule); }
private bool IsAllowed(Account user, int moduleId, string action) { if (user == null || user.Id <= 0 || moduleId == 0 || string.IsNullOrEmpty(action)) return false; var permission = user.Permissions.Where(p => p.MODULEID == moduleId); action = action.Trim(','); if (action.IndexOf(',') > 0) { permission = permission.Where(p => action.ToLower().Contains(p.PERVALUE.ToLower())); } else { permission = permission.Where(p => p.PERVALUE.ToLower() == action.ToLower()); } return permission.Any(); } }
public class ModuleDistinct : IEqualityComparer<Domain.SYS_MODULE> { public bool Equals(Domain.SYS_MODULE x, Domain.SYS_MODULE y) { return x.ID == y.ID; }
public int GetHashCode(Domain.SYS_MODULE obj) { return obj.ToString().GetHashCode(); } }
|
后面我们就用到这个基类,我先给大家看一下这个权限认证在后台是如何使用的,加上这一句就OK了