Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/17.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 Mvc_Security_Access Control_Document Management - Fatal编程技术网

C# ASP.NET MVC中基于文档的安全性

C# ASP.NET MVC中基于文档的安全性,c#,asp.net-mvc,security,access-control,document-management,C#,Asp.net Mvc,Security,Access Control,Document Management,我已经了解ASP.NET MVC中基于用户和角色的安全性。但现在我需要更细粒度的东西 假设我有一个文档列表,其中有些文档是用户授权的,有些文档不是。每个文档在数据库的文档表中都有相应的记录。如果用户具有安全访问权限,则可以下载文档进行查看。如果您具有该角色,还可以添加文档。每个文档都有一个URL,每个文档列表都有一个URL 我想对列表进行安全性调整,以便用户只看到他授权访问的文档。但我还需要对这些列表和文档的URL请求进行身份验证,因为没有任何东西可以阻止用户将他们不再有权访问的文档添加到书签中

我已经了解ASP.NET MVC中基于用户和角色的安全性。但现在我需要更细粒度的东西

假设我有一个文档列表,其中有些文档是用户授权的,有些文档不是。每个文档在数据库的文档表中都有相应的记录。如果用户具有安全访问权限,则可以下载文档进行查看。如果您具有该角色,还可以添加文档。每个文档都有一个URL,每个文档列表都有一个URL

我想对列表进行安全性调整,以便用户只看到他授权访问的文档。但我还需要对这些列表和文档的URL请求进行身份验证,因为没有任何东西可以阻止用户将他们不再有权访问的文档添加到书签中,或者只是在浏览器中键入URL


内置的基于角色的安全模型是否适用于此,还是需要创建单独的、基于表的安全性?我可以将安全性放在我的存储库中,以便已修剪返回的记录,还是应该将其作为控制器的一部分?我是否需要一个安全属性来验证控制器请求,还是应该将其作为前几行代码放在控制器方法中?

@Robert,我想你已经回答了你自己的问题,当你说你应该在它们到达视图之前修剪它们。因此,在您的业务逻辑中,作为对存储库的偏好,您可能希望使用lamda来修剪多余的部分

我认为我永远不会将任何记录返回到用户不允许看到的视图中。为什么增加风险和流量

至于书签,我认为你需要做一些业务逻辑,防止它们在访问权限不再存在时访问url

我认为控制器只是为页面提供数据服务,没有任何逻辑,因此我更喜欢使用业务层方法,因为它看起来确实是一个业务规则


这可能不是您想要的,但除非有更好的方法,否则我将使用它。

我将尝试解释我打算如何在我的项目中实现这一点。该要求与您的要求类似:用户具有具有权限的角色,权限定义、角色权限列表和用户角色列表等都可以更改。因此,在某一时刻,用户可能有权访问某个内容,而在另一时刻,如果管理员更改某个内容,则他无权访问

在我写代码之前,我先回答你们的问题

我需要创建单独的, 基于表的安全性

-对

我能把保险放在我的房间里吗 存储库,以便返回 记录已被删除,或者应该被删除 它是控制器的一部分吗

-我认为安全性应该是业务逻辑的一部分,所以我会把它放在控制器和存储库之间

我是否需要一个安全属性来 验证控制器请求

-在我的项目中,我将它放在属性中,但有时我需要从控制器访问它,但由于我将安全逻辑保留在业务层中,所以我认为这不是一个问题

第一个属性是简单属性,只允许登录用户执行操作:

public class LoggedUserFilterAttribute : ActionFilterAttribute
{
    public bool Logged { get; set; }
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!SessionManager.IsUserLogged)
        {
            filterContext.Result = new RedirectToRouteResult(GetRedirectToNotLoggedRouteValues());
            this.Logged = false;
        }
        else
            this.Logged = true;
    }

    public RouteValueDictionary GetRedirectToNotAuthorizedRouteValues()
    {
        RouteValueDictionary routeValues = new RouteValueDictionary();
        routeValues.Add("action", "NotAuthorized");
        routeValues.Add("controller", "Authorization");
        return routeValues;
    }
    public RouteValueDictionary GetRedirectToNotLoggedRouteValues()
    {
        RouteValueDictionary routeValues = new RouteValueDictionary();
        routeValues.Add("action", "NotLogged");
        routeValues.Add("controller", "Authorization");
        return routeValues;
    }
}
例如,我有一个属性,它只允许超级用户访问它:

public class SuperUserFilterAttribute : LoggedUserFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        base.OnActionExecuting(filterContext);

        if (Logged)
        {
            MyBaseController controller = filterContext.Controller as MyBaseController;
            if (controller == null)
                throw new Exception("Please use MyBaseController instead of built in Controller");

            User loggedUser = controller.Model.UserBO.GetUserByID(SessionManager.LoggedUser.UserID);

            if(!loggedUser.IsSuperUser)
            {
                filterContext.Result = new RedirectToRouteResult(GetRedirectToNotAuthorizedRouteValues());
            }
        }
    }
}
MyBaseController是继承Controller的类,它有一个表示业务对象容器的模型类实例。在控制器操作体中,如果需要,我将检查用户对当前实体的权限,并根据该权限返回正确的视图:

    [LoggedUserFilter]
    public ActionResult LoadSomeEntity(int customerServiceID,int entityID)
    {
        UserRights userPermissionsView = Model.SecurityBO.GetUsersRightsOnEntity(SessionManager.LoggedUser.UserID, entityID);

        if(userPermissionsView.Write) 
            return View("EditEntity",Model.EntityBO.GetEntityByID(entityID));
        if(userPermissionsView.Read) 
            return View("ViewEntity",Model.EntityBO.GetEntityByID(entityID));

        return View("NotAuthorized");     
    }

p、 我不确定我是否能向比我经验丰富得多的人提出建议:),所以,如果我发垃圾邮件,我对此表示歉意。

听起来您喜欢使用DAL/ORM部分类中的业务逻辑的方法。这听起来对吗?是的,但比这更独立。虽然我不介意,但经过思考后,DAL中的部分概念,我更喜欢的方法一直是将其外推到实际的业务层。当然,该层将引用DAL对象,但它将我的业务逻辑与数据库分离。听起来访问权限是一个业务规则,而不是DAL关注的问题;您仍然可以对控制器隐藏安全检查,并且只需执行一次(它也可以用于安全微调)。感谢您的回复。你有正确的想法;我已经看到了应用于用户和角色身份验证的属性模式。我看到其他人在这里发布了一个关于使用属性实现基于表的安全性的问题。这种方法的问题是,您需要访问URL参数才能正确执行。由于该属性无权访问控制器方法的参数,因此您现在必须跳过一些限制来获取它们。我知道,OnAuthorize方法中的AuthorizeAttribute无权访问控制器方法的参数,但我使用的OnActionExecuting中的ActionFilterAttribute有:filterContext.ActionParameters属性返回IDictionary,其中key是参数名,value是传递给方法的值。这是一个很好的观察结果,但对我来说似乎有点太远了。因为我将从我的模型中检索数据,所以我可以在那里对其进行安全性修剪。如果用户没有访问某些记录的权限,它们将不会出现在列表中,并且如果为详细信息视图检索单个记录,我可以检查null并重定向。完全同意您的看法。在矿山项目中,业务逻辑并没有要求粒度方法作为“记录级安全性”。