扩展 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 - 您可以通过传递给AuthorizeCoreHttpContextBase访问路线数据:((MvcHandler)httpContext.Handler).RequestContext.RouteData【参考方案2】:

无论用户是第一次获得授权,还是使用缓存的授权,您都应该将任何必须运行的代码放在AuthorizeCore 中。

如果查看源代码,您可以看到AuthorizeCoreOnAuthorizeOnCacheAuthorization 调用。这允许缓存授权,但仍允许某些操作并做出有关授权的实际决定。

如果您需要 AuthorizationContext 中的某些内容,则可以创建一个属性来保存信息,然后在 AuthorizeCore 方法中访问该信息。

【讨论】:

我希望我能突出你答案的最后一句话。你真的应该加粗。参考@gw0 在接受的答案中的评论,真正不幸的是,出于错误原因使用错误覆盖的建议被投票赞成。 AuthorizeAttribute (MSDN) 的文档明确指出(在线程安全下)“不保证任何实例成员都是线程安全的。” 所以我猜想将信息保存在属性不是一个选项。 @BartVG - 我不确定我是否跟随。线程安全与这个讨论有什么关系?该文本的全部含义是,如果要以多线程方式使用对象,则必须同步对对象的访问。 @Mystere Man:线程安全是你在this answer的评论中提到的事情 @BartVG - 是的,但这与属性无关。线程安全意味着多个线程可以同时读取和写入实例,因此它们需要同步以防止竞争条件。

以上是关于扩展 AuthorizeAttribute 覆盖 AuthorizeCore 或 OnAuthorization的主要内容,如果未能解决你的问题,请参考以下文章

扩展AuthorizeAttribute

WebAPI的AuthorizeAttribute扩展类中获取POST提交的数据

是否可以在 MVC 4 AuthorizeAttribute 中使用异步/等待?

自定义AuthorizeAttribute OnAuthorizationAsync Function

自定义AuthorizeAttribute

创建 AuthorizeAttribute - 我需要知道啥?