HttpConext 对象具有SkipAutorization 属性,用于禁用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 和标题中的文档 ID 和安全信息(我正在使用 OAuth)并执行所有安全检查,如果它们成功,则从数据库中检索 pdf 文档路径,并通过响应将文件提供给客户端。写文件。
我需要以图像形式提供 pdf 页面的预览,为此我使用 ImageResize 和 PdfRenderer 插件。
不幸的是,在我的文件处理程序工作之前不知道 pdf 的路径,并且对于 ImageResizer 对请求采取行动来说为时已晚,因为所有魔法都发生在 PostAuthorizeRequest 中,这(显然)在处理程序运行之前。
为了解决这个问题,我将我的 HttpHandler 重写为 HttpModule,它在 BeginRequest 上执行。如果授权检查失败,则请求在此处被切断。如果它们没问题,那么我使用 PathRewrite 指向生成的 pdf,同时将正确的 Content-Type 和其他标头写入响应。同时我设置了 context.SkipAutorization 标志,因为根据 web.config 配置无法通过直接 url 访问 pdf 文件,如果不跳过授权,管道甚至不会到达 PostAuthorizeRequest。在这种情况下跳过授权是安全的,因为模块已经执行了所有必需的检查。
所以这允许执行流程到达 ImageResizer。但随后 Image resizer 决定它要重新检查 pdf url 上的授权。除非您应用上述解决方法,否则它会失败。
重新检查的理由是什么?在上面的场景中,当 ImageResizer 有工作要做时,它要提供的图像不是出现在 URL 中的图像,并且 asp.net 管道已经完成了身份验证检查,现在我们在 PostAuthorizeRequest 中。这种重新检查在哪些情况下有用?