[英]IIS 7 with URL Rewrite Module 2.0 - setting 401 status codes and the ReturnUrl
我在IIS 7上托管了一个网站,并安装了URL重写模块2.0 。 它由内容管理系统运行,该系统查看URL,如果当前用户无权查看该页面,则返回401错误。 这由ASP.NET URL授权模块处理,然后将其按web.config
文件中指定的形式将页面转到loginUrl页面(表单身份验证)。
这在我的本地计算机-IIS 7和Windows 7上完美运行。
如果该URL是/612/some-string
则用户将被定向到登录页面,位于/66/login?ReturnUrl=/612/some-string
。
URL重写在URL的第一部分查找文档ID。 真正的URL是这样的: index.aspx?documentId=612
不幸的是,当我将其部署到登台服务器时,ReturnUrl不是重写的URL,而是原始URL。 这会引起各种各样的问题。
登台服务器也是安装了URL重写模块2.0的IIS 7。 它是Windows 2008服务器SP2。 两者都运行ASP.NET 3.5。
我唯一的猜测是machine.config
文件对默认httpModules的排序不同,并且.NET表单身份验证模块在URL重写之前就已进入。
我会尽快进行回顾,但与此同时,此问题的经验是什么,可以解决吗?
更新资料
我也尝试改变
Response.StatusCode = 401;
至
FormsAuthentication.RedirectToLoginPage();
这使我有点领先,但仍然将用户引导回尚未重写的URL。
我也可以这样做,而不是设置401:
string currentPage = HttpUtility.UrlEncode(Request.RawUrl);
string loginUrl = FormsAuthentication.LoginUrl + "?ReturnUrl=" + currentPage;
Response.Redirect(loginUrl);
但这看起来很丑。
在Dominick Baier的《开发更多=安全的Microsoft ASP.NET 2.0应用程序》一书的第2章中,有一个ShowPipeline.ashx,它显示了使用HttpHandler在服务器上的完整管道排序:
<%@ WebHandler Class='ShowPipeline' Language='c#' %>
using System;
using System.Web;
using System.Reflection;
using System.ComponentModel;
// shows which modules have registered for which event
// add a ?asm=true query string parameter to also show the assemblies
public class ShowPipeline : IHttpHandler
{
static bool _showAssemblies = false;
// names of the pipeline events
static string[] _handlerNames = {
"BeginRequest",
"AuthenticateRequest",
"DefaultAuthentication",
"PostAuthenticateRequest",
"AuthorizeRequest",
"PostAuthorizeRequest",
"ResolveRequestCache",
"PostResolveRequestCache",
"AcquireRequestState",
"PostAcquireRequestState",
"PreRequestHandlerExecute",
"PostRequestHandlerExecute",
"ReleaseRequestState",
"UpdateRequestCache",
"PostUpdateRequestCache",
"EndRequest"
};
public void ProcessRequest(HttpContext ctx)
{
if (ctx.Request.QueryString["asm"] == "true")
_showAssemblies = true;
ctx.Response.Write("<hr>");
foreach (string s in _handlerNames)
{
_showHandlers(s);
}
ctx.Response.Write("<hr>");
}
public void _showHandlers(string handlerName)
{
HttpResponse r = HttpContext.Current.Response;
object key = _getPrivateAppField("Event" + handlerName);
EventHandlerList ehl = (EventHandlerList)_getPrivateAppField("_events");
MulticastDelegate md = (MulticastDelegate)ehl[key];
if (null != md)
{
r.Output.WriteLine("<h2>{0}</h2>", handlerName);
foreach (Delegate d in md.GetInvocationList())
{
Type tt = d.Target.GetType();
string asm = "";
if (_showAssemblies)
{
asm = string.Format("<font color='red'>[{0}]</font>", tt.Assembly.GetName());
}
r.Output.WriteLine("{0}{1}.<font color='blue'>{2}</font><br>", asm, tt, d.Method.Name);
}
}
}
object _getPrivateAppField(string fieldName)
{
return _getPrivateField(typeof(HttpApplication), fieldName, HttpContext.Current.ApplicationInstance);
}
object _getPrivateField(Type t, string fieldName, object o)
{
return t.GetField(fieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic).GetValue(o);
}
object _getPrivateField(string fieldName, object o)
{
return o.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic).GetValue(o);
}
public bool IsReusable { get { return true; } }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.