处理ASP.NET MVC应用程序中的记录/实体级安全性

时间:2011-11-23 19:29:07

标签: c# asp.net asp.net-mvc security aop

每个人都在做什么来处理ASP.NET MVC应用程序中各个记录的安全性(检索和修改)?此应用程序具有与Web用户界面完全独立的服务/业务层和数据访问层。我已经在使用成员资格和角色提供程序来处理我的应用程序中特定区域/功能的身份验证和授权,但现在我需要保护个人记录。

例如,假设Bob可以创建和编辑自己的FooBar记录。我想确保其他用户无法查看或编辑Bob的记录。我想防止URL操作和/或编程错误。我们可能还希望允许Bob与其他用户共享他的FooBars,允许他们查看但不能编辑他的记录。

我提出了几种方法:

  • 直接在检索和修改查询中对数据访问层执行安全检查。
  • 检查服务层中的安全性,在继续使用业务逻辑之前执行额外的安全性查询。
  • 创建UI和服务层之间存在的安全层。 UI将通过安全层发出所有请求。
  • 使用面向方面编程(AOP)。创建安全性方面并使用安全属性修饰服务层方法。

我在以前的项目中的数据访问层(在查询中)中已经完成了安全性,并且它总是变得一团糟。我想知道其他人在做什么,以及你用什么框架来帮助你(AOP框架。)

3 个答案:

答案 0 :(得分:2)

我总是采用第二和/或第三种方法 - 在UI和逻辑处理程序之间的某个显式安全层。

AOP听起来像是完全失去对代码的控制权的一种方式,DAL中的安全性听起来像是错误的方法,因为它混合了不同的职责。

答案 1 :(得分:2)

我认为在任何地方放置逻辑都可能是个问题。我有类似的情况。让我解释一下我是如何处理它的。

public class FooBarController : Controller
{

    //this is easy as compared to edit
    [Authorized]
    public ActionResult Create()
    {


    }


    [AjaxAuthorize(Roles = "Administrator")]    
    public ActionResult Edit(int id)
    {


    }
}

public class AjaxAuthorizeAttribute : AuthorizeAttribute
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {


        var id = filterContext.RouteData.Values["id"];
        // Here you can check if the id belongs to logged in user
        var content = SomeRepository.GetById(id);
        if (contet.OwnerId=LoggedInUser.Id)
           return;

        //otherwise check if logged in user is from some Admin or other role.


        string redirectPage = "/account/logon";
        var roles = base.Roles.Trim().Split(',');
        bool CanAccess = false;

        //If no role is there
        if (base.Roles.Equals(string.Empty) || roles.Count() == 0)
        {
            CanAccess = true;
        }
        else
        {
            foreach (var item in roles)
            {
                CanAccess = filterContext.HttpContext.User.IsInRole(item);
                if (CanAccess)
                    break;
            }
        }

        var request = filterContext.RequestContext.HttpContext.Request;
        if (request.IsAjaxRequest())
        {
            if (!(request.IsAuthenticated && CanAccess))
            {
                filterContext.Result = new AjaxAwareRedirectResult(redirectPage);
                return;
            }
        }

        base.OnAuthorization(filterContext);
    }
}

public class AjaxAwareRedirectResult : RedirectResult
{
    public AjaxAwareRedirectResult(string url)
        : base(url)
    {
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (context.RequestContext.HttpContext.Request.IsAjaxRequest())
        {

            string destinationUrl = UrlHelper.GenerateContentUrl(Url, context.HttpContext);

            JavaScriptResult result = new JavaScriptResult()
            {
                Script = "window.location='" + destinationUrl + "';"
            };
            result.ExecuteResult(context);
        }
        else
            base.ExecuteResult(context);
    }
}

现在,您可以允许所有者或管理员编辑内容。 我将此属性称为Ajax,因为它也将处理AjaxRequest。 我希望这有帮助。

此致

Parinder

答案 2 :(得分:0)

public class Entity
{
     public Right[] Rights { get; set; }         
}

public class Right
{
     public User user {get;set;}
     public Permission[] permissions {get;set;}

}

public class Foo : Entity
{


}

public class Bar : Entity
{

}

在上述方法中,存在基类Entity,其存储特定用户对该实体的权限。从Entity类继承您要保护的所有类。