开发者

Enforce security check in ASP.NET MVC?

开发者 https://www.devze.com 2023-02-15 10:28 出处:网络
I am implementing a collaborative web gallery, and I have a few roles for each user: Admin DeleteImage DeleteOwnImage

I am implementing a collaborative web gallery, and I have a few roles for each user:

  1. Admin
  2. DeleteImage
  3. DeleteOwnImage
  4. etc..

For any controller-action, we can apply [Authorize] tag to them plus which roles we want to allow, right? It is fine for Admin/DeleteImage since these two are global; but my question is, like DeleteOwnImage is kind of contextual, in order to determine whether it is valid开发者_如何学Go, we need:

  1. To know what image it is trying to delete (from request)
  2. Retrieve the owner of that image (from service or repository)
  3. Compare current user = that owner

Obviously [Authorize] is not enough to do so, but is it possible to do that on custom ActionFilters? Any hint?


Yes, this is possible with a custom action filter. You can extend from AuthorizeAttribute, the most basic implementation being something like:

public class OwnImageAuthorizeAttribute : AuthorizeAttribute {
    public string ImageIdKey { get; set; }

    protected override bool AuthorizeCore(HttpContextBase httpContext) {
    bool authorized = false;
    // Get the current user
    var currentUser = ...;
    // Get the image ID, whether it is in the route or querystring
    int imageId
    if(int.TryParse(httpContext.RouteData.Values(ImageIdKey), out imageId)) {
        // From querystring: httpContext.Request.Querystring[ImageIdKey]
        // Authorize the user
        authorized = YourMethodToCheckIfUserIsOwner(currentUser, imageId);
    }

    return authorized;
}

Then, decorate your method:

[OwnImageAuthorize(ImageIdKey = "imageId")]
public ActionResult MyAction() { }

You can find some more details here.


You can easily add something like this in an ActionFilter, Just add an action filter with OnActionExecuting implemented.

Although, depending on your DB schema this could be achieved on the DB level with your query. You could just delete when owner equals recieved recieved id. (I mean, inside the action method and not in the filter)

EDIT: If you're using some kind of IOC container for the repositories, you should look around for the new IOC features in MVC3 (if you're using MVC3) to inject dependencies into your action filters.

http://bradwilson.typepad.com/blog/2010/07/service-location-pt4-filters.html

EDIT2:

BTW, I myself don't really like doing too much business logic in ActionFilters, especially involving calls to the DB. Even more when it's something very specific that'll be used for one action.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号