扩展 AuthorizeAttribute 覆盖 AuthorizeCore 或 OnAuthorization
Posted
技术标签:
【中文标题】扩展 AuthorizeAttribute 覆盖 AuthorizeCore 或 OnAuthorization【英文标题】:Extend AuthorizeAttribute Override AuthorizeCore or OnAuthorization 【发布时间】:2011-10-15 04:45:06 【问题描述】:使用 ASP.NET MVC 我正在创建一个自定义 Authorize 属性来处理一些自定义授权逻辑。我看过很多例子,这很简单,但我的问题是哪种方法最好覆盖,AuthorizeCore 还是 OnAuthorization?我已经看到了许多覆盖其中一个或另一个的例子。有区别吗?
【问题讨论】:
签出MVC4中的源代码,aspnetwebstack.codeplex.com/SourceControl/changeset/view/… 【参考方案1】:线索在返回类型中:
AuthorizeCore
返回一个布尔值 - 这是决策代码。这应该仅限于查看用户的身份和测试他们所处的角色等等。基本上它应该回答这个问题:
Do I want this user to proceed?
它不应该“在旁边”执行任何额外的活动。
OnAuthorize
返回 void - 这是您放置此时需要发生的任何 功能 的地方。例如写入日志,在会话中存储一些数据等。
【讨论】:
不幸的是 AuthorizeCore 不包含我需要的 AuthorizationContext(用于访问 RouteData 并基于它做出决策),因此我看到的唯一方法是使用 OnAuthorize。 为什么AuthorizationContext
不传递到AuthorizeCore
?这似乎是一个重大缺陷。
@Jaz - AuthorizeCore
从两个地方调用,一个来自OnAuthorize
,另一个来自OnCacheAuthorization
。后一种情况,没有AuthorizationContext
,必须是线程安全的。
@gw0 - 您可以通过传递给AuthorizeCore
的HttpContextBase
访问路线数据:((MvcHandler)httpContext.Handler).RequestContext.RouteData
【参考方案2】:
无论用户是第一次获得授权,还是使用缓存的授权,您都应该将任何必须运行的代码放在AuthorizeCore
中。
如果查看源代码,您可以看到AuthorizeCore
被OnAuthorize
和OnCacheAuthorization
调用。这允许缓存授权,但仍允许某些操作并做出有关授权的实际决定。
如果您需要 AuthorizationContext 中的某些内容,则可以创建一个属性来保存信息,然后在 AuthorizeCore 方法中访问该信息。
【讨论】:
我希望我能突出你答案的最后一句话。你真的应该加粗。参考@gw0 在接受的答案中的评论,真正不幸的是,出于错误原因使用错误覆盖的建议被投票赞成。 AuthorizeAttribute (MSDN) 的文档明确指出(在线程安全下)“不保证任何实例成员都是线程安全的。” 所以我猜想将信息保存在属性不是一个选项。 @BartVG - 我不确定我是否跟随。线程安全与这个讨论有什么关系?该文本的全部含义是,如果要以多线程方式使用对象,则必须同步对对象的访问。 @Mystere Man:线程安全是你在this answer的评论中提到的事情 @BartVG - 是的,但这与属性无关。线程安全意味着多个线程可以同时读取和写入实例,因此它们需要同步以防止竞争条件。以上是关于扩展 AuthorizeAttribute 覆盖 AuthorizeCore 或 OnAuthorization的主要内容,如果未能解决你的问题,请参考以下文章
WebAPI的AuthorizeAttribute扩展类中获取POST提交的数据
是否可以在 MVC 4 AuthorizeAttribute 中使用异步/等待?