基于asp.net mvc中角色的自定义用户授权

我已经为我的用户创建了自定义身份validation和授权。我面临的问题是如何让mvc检查我的users表中的角色是否与我的控制器上的[Authorize(Role)]匹配,以便将httpauthorised设置为true。以下是我的习惯课程。

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] public class CustomAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { filterContext.Controller.TempData["ErrorDetails"] = "You must be logged in to access this page"; filterContext.Result = new RedirectResult("~/User/Login"); return; } if (filterContext.HttpContext.Request.IsAuthenticated) { using (var db = new GManagerDBEntities()) { var authorizedRoles = (from u in db.Users where u.Username == filterContext.HttpContext.User.Identity.Name select u.Role).FirstOrDefault(); Roles = String.IsNullOrEmpty(Roles) ? authorizedRoles.ToString() : Roles; } } if (filterContext.Result is HttpUnauthorizedResult) { filterContext.Controller.TempData["ErrorDetails"] = "You do nat have necessary rights to access this page"; filterContext.Result = new RedirectResult("~/User/Login"); return; } } public CustomAuthorizeAttribute(params object[] roles) { if (roles.Any(r => r.GetType().BaseType != typeof(Enum))) throw new ArgumentException("roles"); this.Roles = string.Join(",", roles.Select(r => Enum.GetName(r.GetType(), r))); } } 

下面是我的装饰控制器

  [CustomAuthorize(Role.Administrator)] [HttpGet] public ActionResult CreateEmployees() { return View(); } 

和我的角色

 public enum Role { Administrator = 1, UserWithPrivileges = 2, User = 3, } 

和模型

 public class UserModel { public int UserID { get; set; } [Required] [Display(Name="Username:")] public string Username { get; set; } [Required] public string Password { get; set; } public int Role { get; set; } } 

看到意见清楚的牧师

我试图解决这个问题的链接,但我似乎无法将它拼凑在一起MVC 3授权自定义角色 http://forums.asp.net/p/1573254/3948388.aspx

带有角色的MVC 4中的自定义授权属性

使用@VikasRana共享的链接http://www.codeproject.com/Articles/578374/AplusBeginner-splusTutorialplusonplusCustomplusF

我摆脱了我的枚举角色和我的方法

 public CustomAuthorizeAttribute(params object[] roles) { ...} 

然后我将模型中的角色更改为字符串,例如User.Role =“Admin”而不是int。 在我的onAuthorization方法中,我将其更改为:

 ` public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); if (!filterContext.HttpContext.User.Identity.IsAuthenticated) { filterContext.Controller.TempData["ErrorDetails"] = "You must be logged in to access this page"; filterContext.Result = new RedirectResult("~/User/Login"); return; } if (filterContext.Result is HttpUnauthorizedResult) { filterContext.Controller.TempData["ErrorDetails"] = "You don't have access rights to this page"; filterContext.Result = new RedirectResult("~/User/Login"); return; } } 

并在我的global.asax中添加了这个。

 protected void Application_PostAuthenticateRequest(Object sender, EventArgs e) { if (FormsAuthentication.CookiesSupported == true && Request.IsAuthenticated== true) { if (Request.Cookies[FormsAuthentication.FormsCookieName] != null) { try { //let us take out the username now string username = FormsAuthentication.Decrypt(Request.Cookies[FormsAuthentication.FormsCookieName].Value).Name; string roles = string.Empty; using (GManagerDBEntities db = new GManagerDBEntities()) { User user = db.Users.SingleOrDefault(u => u.Username == username); roles = user.Role; } //let us extract the roles from our own custom cookie //Let us set the Pricipal with our user specific details HttpContext.Current.User = new System.Security.Principal.GenericPrincipal( new System.Security.Principal.GenericIdentity(username, "Forms"), roles.Split(';')); } catch (Exception) { //something went wrong } } } } 

上面的方法并不理想。它可以为每个简单的页面请求运行大约3次或更多次。

所以这里是解决方案2:更好的解决方案实现自定义角色提供程序,因为我们已经在使用自定义角色实现。只需点击此链接http://techbrij.com/custom-roleprovider-authorization-asp-net-mvc

感谢Gotalove在Global.asax中使用此方法。 对于任何尝试使用entity framework进行自定义表单身份validation(FormsAuthentication,FormsAuthenticationTicket)的人来说,这里有一些帮助。

登录控制器SetAuthTicket

 protected void GetRoles(int UserID) { var db = new ResearchSurveysEntities(); string[] getRoles = { }; try { var query = from p in db.UserProfiles join i in db.webpages_UsersInRoles on p.UserId equals i.UserId join r in db.webpages_Roles on i.RoleId equals r.RoleId where p.UserId == UserID select new { p.UserId, r.RoleName }; if (query.Count() > 0) { List gRoles = new List(); foreach (var item in query) { gRoles.Add(item.RoleName); } getRoles = gRoles.ToArray(); } roles = String.Join("|", getRoles); } catch (Exception ex) { WebUtilities wu = new WebUtilities(); wu.NotifyWebmaster(ex.ToString(), "Get roles for AdminUserID: " + UserID.ToString(), string.Empty, "Login Error"); } finally { db.Dispose(); } } 

WebConfig

    

Global.asax(来自上面的例子)

 protected void Application_AuthenticateRequest(Object sender, EventArgs e) { HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName]; if (authCookie == null || authCookie.Value == "") return; FormsAuthenticationTicket authTicket; try { authTicket = FormsAuthentication.Decrypt(authCookie.Value); } catch { return; } // retrieve roles from UserData string[] roles = authTicket.UserData.Split('|'); if (Context.User != null) Context.User = new GenericPrincipal(Context.User.Identity, roles); }