我编写了一个HttpModule来拦截,评估和授权请求,检查记录的用户是否具有对所请求的url的适当访问权限,这是用ASP.NET 2.0编写的一个非常古老的遗留系统(网页,而不是Web应用程序),客户不希望移植到更新的框架。已在登录时加载和缓存限制。
一切正常,除非某个页面包含<asp:MultiView>
组件或者有一个启动ajax方法的按钮。当其中一种情况发生,并且用户无权访问该网址时,会弹出一个警告框,其中显示“未知错误”消息,该消息来自ThreadAbortException
方法引发的Response.End()
。
问题是:为什么我的“未授权”消息被异常中的“未知错误”覆盖,仅在这两种情况下?
是否有办法使用数据库和缓存执行Url授权系统,而不会使Web.config
与旧的ASP.NET样本等角色混杂在一起?
// My module init method.
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
// PreRequestHandlerExecute is the first stage at ASP.NET Pipeline
// where we could get a fulfilled Session variable
}
private void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication application = (HttpApplication)sender;
HttpContext context = application.Context;
// additional request filtering/validation/etc.
LoggedUser user = (LoggedUser)application.Session["user"];
string path = context.Request.Path;
// more checks and rules...
if (!checkUserAuthorization(path, user))
{
context.Response.Write("<script>alert('Unauthorized. Contact your manager.');</script>");
context.Response.Write("<script>window.history.back();</script>");
context.Response.StatusCode = 403;
context.Response.End();
}
}
编辑:我已经尝试过的(没有目标):
Response.OutputStream.Close();
Response.Flush();
HttpApplication.CompleteRequest();
答案 0 :(得分:0)
它是设计的。你必须忽略它并为该异常添加一个catch。
try {
context.Response.End();
}
catch{}
答案 1 :(得分:0)
<强>前言强>
经过大量研究,终于得到了它。考虑到ASP.NET 2.0,关于AJAX操作,我工作的项目使用名为&#34; Atlas&#34;,which in turn got renamed to ASP.NET AJAX的Microsoft组件。在编写此系统时,开发人员使用beta ASP.NET AJAX(代号&#34; Atlas&#34;)来解决所有ajax和部分渲染需求。
我需要深入挖掘源代码(感谢Reflector),以便了解并检查从哪里开始#34;未知错误&#34;来了。
在Microsoft.Web.Atlas中,有一个名为Microsoft.Web.Resources.ScriptLibrary.*.Atlas.js
的文件(其中*
可以是Debug
或Release
),它在运行时通过{ {1}}&#34;代理&#34;。
这个javascript文件有一个错误,因为它希望ASP.NET请求总是返回一个WebResource.axd
响应代码,在我的代码中它没有发生(我回复了{{ 1}}我模块的代码。)
<强>代码强>
来自HTTP 200 (OK)
的{{1}}:
403 Forbidden
从此代码中,我们可以看到,由于响应代码不是Microsoft.Web.Resources.ScriptLibrary.*.Atlas.js
,因此WebResource.axd
变量不会被设置,而此this._onFormSubmitCompleted = function(sender, eventArgs) {
var isErrorMode = true;
var errorNode;
var delta;
if (sender.get_statusCode() == 200) {
delta = sender.get_xml();
if (delta) {
errorNode = delta.selectSingleNode("/delta/pageError");
if (!errorNode) {
isErrorMode = false;
}
}
}
if (isErrorMode) {
if (errorNode) {
pageErrorMessage = errorNode.attributes.getNamedItem('message').nodeValue;
}
else {
pageErrorMessage = 'Unknown error';
}
this._enterErrorMode(pageErrorMessage);
return;
}
// Code continues.
}
语句将始终为{ {1}}。
在这种情况下,我有两个选项:始终返回200 OK
并修改所有包含errorNode
的网页,并在每个网页上添加if (errorNode)
标记,或取代该脚本如果您考虑false
个回复,请将其加载到主页面的HTTP 200
标记下方。
当使用ScriptManager和UpdatePanels(官方的here),通过订阅<atlas:ScriptManager>
事件)时,有很多关于如何进行正确错误处理的教程,但这个beta版本(阿特拉斯)根本没有这个活动。