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

Got*_*ode 6 c# asp.net asp.net-mvc authorization asp.net-mvc-4

我为我的用户创建了自定义身份验证和授权.我面临的问题是如何让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)));
    }
}
Run Code Online (Sandbox Code Playgroud)

下面是我的装饰控制器

 [CustomAuthorize(Role.Administrator)]
    [HttpGet]
    public ActionResult CreateEmployees()
    {
        return View();
    }
Run Code Online (Sandbox Code Playgroud)

和我的角色

public enum Role
{
    Administrator = 1,
    UserWithPrivileges = 2,
    User = 3,
}
Run Code Online (Sandbox Code Playgroud)

和模型

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; }
}
Run Code Online (Sandbox Code Playgroud)

看到清晰的视野pastie pastie

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

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

Got*_*ode 4

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

我摆脱了枚举角色和方法

public CustomAuthorizeAttribute(params object[] roles)
    { ...}
Run Code Online (Sandbox Code Playgroud)

然后我将模型中的 Role 更改为字符串,例如 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;
        }
        }
Run Code Online (Sandbox Code Playgroud)

并在我的 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
                }
            }
        }
    }   
Run Code Online (Sandbox Code Playgroud)

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

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