开发者

AuthorizeAttribute MVC - restrict access to user created content

So I read about how implementing your own authorization routines are bad!

http://www.nashcoding.com/2011/02/05/using-the-forms-authentication-membership-provider-on-appharbor/

And I got scared, because I've been implementing my actions as such (example, preventing access to account details if authenticated user is not the logged in user)

public ActionResult DisplayAccount(int someid){
    Account a = context.Accounts.Single(a => a.id == someid);

    // currentUserId() returns userid from FormsAuthentication
    if (!a.owner == currentUserId()){
        /* Not Authorised! */
    }
}

Which apparently means it will break if ASP decides to cache my action (so the action doesn't even get executed).

So I'm now looking into using AuthorizeAttribute to do what I need to do, which is

  • prevent access to an action if not authenticated
  • check if authenticated user has access to the retrieved resource

However whenever I think about it, I can't think about how to implement the 2nd point. Roles don't work because its on a site wide level, but within the application there users have roles as well (e.g. Owner, Moderator, Contributor, User etc.), and they only have these roles wi开发者_开发百科thin their respective parts of the application (e.g. owner of thread, contributor to wiki, moderator of forum etc.)

I have run into several examples of overriding AuthorizeCore. I can sort of imagine creating multiple AuthorizeAttribute subclasses for each resource I have (luckily not many), But just by looking at it, does that mean I have to query the database everytime I hit that action to ensure that the logged in user should be able to access that data, then query the database in my action to get the model, instead of doing that in my query?

So my questions are

  • am I getting too worried about caching too much? Will any of the following happen
    • website caches user A details, which is rendered on user B's screen?
    • website caches admin version of a page (with edit controls), and normal user sees cached version?
  • Using AuthorizeAttribute is a given, but how do I achieve what I need to do in point 2 without having to hit the database prior to the Action? Or what is the best way to achieve it in any case.
  • Or do I only use AuthorizeAttribute to determine if the user is logged in, and do other checking logic in my action?

Anyway, I hope this post isn't treading on any old paths (I couldn't find anything on this that I found definitive)


Edit: I guess, if I don't enable caching this problem wouldn't occur, is this correct?


Edit: for now, I am going to going to use vanilla AuthorizeAttribute, then check resource level access in my actions, then make sure I don't use caching for any authenticated actions. Hopefully will get more answers for this over the week.


I used the following approach in a recent project, by creating a DataRightsAttribute that used an enumeration for each supported model type. It works by first extracting the id from the route data, formcollection or querystring. Then it queried up the model type determined by the enum, and did the appropriate check to see if the current user is authorized to access it.

Usage was like this:

[DataRights(ModelType.Customer)]

This was used alongside AuthorizeAttribute (which we overrided), and never noticed any problems with caching.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜