AuthorizeAttribute MVC - 限制对用户创建的内容的访问

发布于 2024-12-09 21:45:29 字数 1685 浏览 0 评论 0原文

所以我读到了关于实施自己的授权例程是多么糟糕!

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

我很害怕,因为我一直在实施我的操作本身(例如,如果经过身份验证的用户不是登录用户,则阻止访问帐户详细信息)

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! */
    }
}

这显然意味着如果 ASP 决定缓存我的操作(因此该操作甚至不会被执行),它将中断。

所以我现在正在考虑使用 AuthorizeAttribute 来做我需要做的事情,即

  • 如果未经身份验证则阻止访问操作
  • ,检查经过身份验证的用户是否有权访问检索到的资源

但是每当我想到它时,我就无法考虑如何实现第2点。角色不起作用,因为它在站点范围内,但在应用程序中,用户也有角色(例如所有者、主持人、贡献者、用户等),并且他们仅在应用程序的各自部分中具有这些角色(例如线程的所有者、wiki 的贡献者、论坛的版主等)

我遇到过几个覆盖 AuthorizeCore 的示例。我可以想象为我拥有的每个资源创建多个 AuthorizeAttribute 子类(幸运的是不多),但是只要看看它,这是否意味着我每次点击该操作时都必须查询数据库以确保登录的用户应该是能够访问该数据,然后在我的操作中查询数据库以获取模型,而不是在我的查询中执行此操作?

所以我的问题是

  • 我是否太担心缓存太多了?是否会出现以下情况
    • 网站缓存用户 A 的详细信息,并将其呈现在用户 B 的屏幕上?
    • 网站缓存页面的管理员版本(带有编辑控件),普通用户会看到缓存版本吗?
  • 使用 AuthorizeAttribute 是给定的,但如何实现第 2 点中需要做的事情,而不必在操作之前访问数据库?或者在任何情况下实现它的最佳方法是什么。
  • 或者我是否只使用 AuthorizeAttribute 来确定用户是否已登录,并在我的操作中执行其他检查逻辑?

不管怎样,我希望这篇文章不会走上任何旧的道路(我找不到任何关于此的明确内容)


编辑:我想,如果我不启用缓存,这个问题就不会发生,这是正确的吗?


编辑:现在,我将使用普通的 AuthorizeAttribute,然后检查我的操作中的资源级别访问权限,然后确保我不会对任何经过身份验证的操作使用缓存。希望本周能得到更多答案。

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 within 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦行七里 2024-12-16 21:45:29

我在最近的项目中使用了以下方法,通过创建一个 DataRightsAttribute,该 DataRightsAttribute 对每个受支持的模型类型使用枚举。它的工作原理是首先从路由数据、表单集合或查询字符串中提取 id。然后它查询由枚举确定的模型类型,并进行适当的检查以查看当前用户是否有权访问它。

用法是这样的:

[DataRights(ModelType.Customer)]

它与 AuthorizeAttribute(我们重写)一起使用,并且从未注意到缓存有任何问题。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文