HttpConext对象有SkipAutorization property,用于禁用UrlAuthorizationModule中的授权检查,这是标准asp.net管道的一部分。
ImageResizer直接在普通的asp.net管道之外调用UrlAuthorizationModule.CheckUrlAccessForPrincipal。因此,SkipAutorization属性不受尊重。
解决方法是:
protected void Application_Start(object sender, EventArgs e)
{
// Ask ImageResizer not to re-check authorization if it's skipped
// by means of the context flag
Config.Current.Pipeline.OnFirstRequest +=
(m, c) =>
{
Config.Current.Pipeline.AuthorizeImage +=
(module, context, args) =>
{
if (context.SkipAuthorization)
{
args.AllowAccess = true;
}
};
};
}
这里的外部OnFirstRequest是为了确保在加载了所有插件之后发生了AuthorizeImage订阅,因此它是链中最后一个要执行的。
我不喜欢这种解决方法,因为它非常依赖于实现。例如,如果ImageResizer插件加载从onFirstRequest移动到其他地方,它将会中断。
如果在ImageResizer本身修复了它会很好。我建议将InterceptModule中的额外Autorization检查更改为以下内容:
//Run the rewritten path past the auth system again, using the result as the default "AllowAccess" value
bool isAllowed = true;
if (canCheckUrl) try {
isAllowed = conf.HonourSkipAutorization && app.Context.SkipAuthorization
|| UrlAuthorizationModule.CheckUrlAccessForPrincipal(virtualPath, user, "GET");
} catch (NotImplementedException) { } //For MONO support
这是合适的,还是有更好的解决方案?
在问题的最后部分,我将描述我的用例,阅读完全是可选的,但它提供了这个查询的透视。
在asp.net应用程序中,我有一个提供pdf文档的HttpHandler。它接受url和headers中的文档ID和安全信息(我正在使用OAuth)并执行所有安全检查,如果成功,则从数据库中检索pdf文档路径,并通过Response将文件提供给客户端。 WriteFile的。
我需要提供pdf页面的预览作为图像,我正在使用带有PdfRenderer插件的ImageResize。
不幸的是,直到我的文件处理程序工作之前才知道pdf的路径,而且ImageResizer对请求采取行动为时已晚,因为所有的魔法都发生在PostAuthorizeRequest中(显然)在处理程序运行之前。
为了解决这个问题,我将HttpHandler重新编写为HttpModule,它在BeginRequest上执行。如果授权检查失败,则请求在那里被切断。如果它们没问题,那么我使用PathRewrite指向生成的pdf,同时将正确的Content-Type和其他标题写入响应。同时我设置了context.SkipAutorization标志,因为根据web.config配置,无法通过直接URL访问pdf文件,如果不跳过授权,管道甚至不会进入PostAuthorizeRequest。在这种情况下,可以安全地跳过授权,因为模块已经执行了所有必需的检查。
因此,这允许执行流程到达ImageResizer。但是,Image resizer决定要重新检查pdf网址上的授权。除非您应用上述解决方法,否则会失败。
重新检查的理由是什么?在上面的方案中,当ImageResizer有工作要做时,它要提供的图像不会出现在URL和auth检查中已经完成了asp.net管道,现在我们在PostAuthorizeRequest。这种重新检查在哪些情况下有用?
答案 0 :(得分:1)
更新:最新版本的ImageResizer尊重HttpContext.SkipAuthorization布尔值,不再需要事件处理程序。
你的解决方法正是解决这个问题的正确方法,而且是可以前瞻的。
重新检查是因为
ImageResizer应该尊重HttpContext.SkipAuthorization ;并且可能会在将来的版本中发布。
也就是说,涉及AuthorizeImage
的解决方法实际上就是我的建议。我不知道它如何比SkipAuthorization
本身更脆弱;事实上无论ImageResizer将来如何重新排序事件都应该有效。
ImageResizer尊重管道中事件的顺序 - 在PostAuthorize完全正确之前发生授权的V2(尽管如果您希望在BeginRequest期间支持额外的前端调整大小,它可以移动到PreAuthorize)。
此外,使用RewritePath提供原始PDF比调用WriteFile更有效,特别是在IIS6 +上,正如您可能发现的那样。