Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# asp.net mvc中基于角色的自定义用户授权_C#_Asp.net_Asp.net Mvc_Asp.net Mvc 4_Authorization - Fatal编程技术网

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

C# asp.net mvc中基于角色的自定义用户授权,c#,asp.net,asp.net-mvc,asp.net-mvc-4,authorization,C#,Asp.net,Asp.net Mvc,Asp.net Mvc 4,Authorization,我已经为我的用户创建了自定义身份验证和授权。我面临的问题是如何让mvc检查我的用户表中的角色是否与控制器上的[授权(角色)]匹配,以便将HttpAuthorized设置为true。下面是我的CustomAuthorized类 [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] public class CustomAuthorizeA

我已经为我的用户创建了自定义身份验证和授权。我面临的问题是如何让mvc检查我的用户表中的角色是否与控制器上的[授权(角色)]匹配,以便将HttpAuthorized设置为true。下面是我的CustomAuthorized类

 [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

我在试图解决这一问题的过程中查看了一些链接,但我似乎无法将它们拼凑在一起


使用@VikasRana共享的链接

我放弃了枚举角色和方法

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:更好的解决方案
实现自定义角色提供程序,因为我们已经在使用自定义角色实现。只需点击此链接即可。感谢在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();
        }
    }

看一看我希望使用一个表和一个角色作为一个整数,但如果所有操作都失败,我将创建一个角色表并实施您的建议@VikasRanaI尝试根据您的链接对此进行更改,但仍然没有幸运最终管理我没有放置“受保护的无效应用程序”PostAuthenticateRequest(对象发送方,事件参数e)'global.asax中的方法
<authentication mode="Forms">
  <forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
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);
    }