首页 文章

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

提问于
浏览
6

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

看到意见清晰pastie

我试图解决这个问题的链接,但我似乎无法把它拼凑起来MVC 3 Authorize custom roles http://forums.asp.net/p/1573254/3948388.aspx

Customized authorization attribute in MVC 4 with Roles

2 回答

  • 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次或更多次 .

    So here is solution 2:better solution 实现自定义角色提供程序,因为我们已经在使用自定义角色实现 . 只需按照此链接http://techbrij.com/custom-roleprovider-authorization-asp-net-mvc

  • 1

    感谢Gotalove在Global.asax中使用此方法 . 对于任何尝试使用实体框架进行自定义表单身份验证(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<string> gRoles = new List<string>();
                    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

    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login" timeout="2880" />
    </authentication>
    

    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);
        }
    

相关问题