【问题标题】:How to elegantly handle ReturnUrl when using UrlRewrite in ASP.NET 2.0 WebForms在 ASP.NET 2.0 WebForms 中使用 UrlRewrite 时如何优雅地处理 ReturnUrl
【发布时间】:2010-12-22 03:15:08
【问题描述】:

我有一个包含多个要限制访问的 .aspx 页面的文件夹。我已使用<deny users="?"/> 将 web.config 添加到该文件夹​​中。

问题是当我使用 UrlRewrite 时,ReturnUrl 是使用 .aspx 文件的物理路径自动生成的。

有没有办法在不进行手动身份验证检查和重定向的情况下操作 ReturnUrl?有没有办法从代码隐藏或 web.config 设置 ReturnUrl?

编辑:应用程序正在使用 ASP.NET 2.0 WebForms。我不能使用 3.5 路由。

编辑 2:似乎永远不会捕获 401 状态代码。它为受保护的页面返回 302,并使用 ReturnUrl 重定向到登录页面。它不会为受保护的页面返回 401。嗯……有趣……参考:http://msdn.microsoft.com/en-us/library/aa480476.aspx

这让事情变得更难...我可能必须编写反向重写映射规则以正则表达式匹配 ReturnUrl 并在它不返回 401 时替换它...如果它确实返回 401 我可以将 RawUrl 设置为 Response.RedirectLocation或将 ReturnUrl 替换为 RawUrl。

还有人有其他想法吗?

【问题讨论】:

  • 还有其他人有其他建议吗?

标签: asp.net url-rewriting webforms forms-authentication returnurl


【解决方案1】:

检查一下。希望这会有所帮助。

#region [ Imports ]

using System;
using System.Web;
using System.Web.Security;

#endregion

namespace Foo.Handlers
{

    public class AuthModule : IHttpModule
    {

        #region IHttpModule Members

        public void Init(HttpApplication application)
        {
            application.PostReleaseRequestState += delegate(object s, EventArgs e)
                {
                    if (application.Response.StatusCode == 401)
                        application.Response.Redirect(FormsAuthentication.LoginUrl + "?ReturnUrl=" + HttpUtility.UrlEncode(application.Request.RawUrl), true);
                };
        }

        public void Dispose() { }

        #endregion

    }

}

<modules>
  <add name="AuthModule" type="Foo.Handlers.AuthModule, Foo"/>
</modules>

【讨论】:

  • 谢谢。我会试试这个。
  • 中间没有机会拦截用 RawUrl 替换 ReturnUrl。
  • 状态码 401 从未被捕获...它进入受保护页面 (302) -> 使用 ReturnUrl (200) 登录。
【解决方案2】:

创建以下控件适配器以使用 for action 属性重写表单标记。我将此 ASP.NET 2.0 应用程序与Intelligencia url 重写器结合使用。我是从这个blog post from the Gu 得到的。

把这个类放到你的 App_Code 文件夹中:

using System.IO;
using System.Web;
using System.Web.UI;

public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter
{
    protected override void Render(HtmlTextWriter writer)
    {
        base.Render(new RewriteFormHtmlTextWriter(writer));
    }
}

public class RewriteFormHtmlTextWriter : HtmlTextWriter
{
    public RewriteFormHtmlTextWriter(TextWriter writer) : base(writer)
    {
        base.InnerWriter = writer;
    }

    public RewriteFormHtmlTextWriter(HtmlTextWriter writer) : base(writer)
    {
        this.InnerWriter = writer.InnerWriter;
    }

    public override void WriteAttribute(string name, string value, bool fEncode)
    {

        // If the attribute we are writing is the "action" attribute, and we are not on a sub-control, 
        // then replace the value to write with the raw URL of the request - which ensures that we'll
        // preserve the PathInfo value on postback scenarios

        if ((name == "action"))
        {
            if (HttpContext.Current.Items["ActionAlreadyWritten"] == null)
            {

                // Because we are using the UrlRewriting.net HttpModule, we will use the 
                // Request.RawUrl property within ASP.NET to retrieve the origional URL
                // before it was re-written.  You'll want to change the line of code below
                // if you use a different URL rewriting implementation.
                value = HttpContext.Current.Request.RawUrl;

                // Indicate that we've already rewritten the <form>'s action attribute to prevent
                // us from rewriting a sub-control under the <form> control
                HttpContext.Current.Items["ActionAlreadyWritten"] = true;

            }
        }
        base.WriteAttribute(name, value, fEncode);
    }
}

然后,在您的 App_Browsers 文件夹中创建此 .browser 文件:

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.HtmlControls.HtmlForm" adapterType="FormRewriterControlAdapter" />
    </controlAdapters>
  </browser>
</browsers>

【讨论】:

  • 似乎这个负责回发页面的 URL。我正在寻找的是当您点击未经身份验证的受限页面时自动生成的 ReturnUrl 查询字符串的干净重写 Url。
  • 我相信它也应该这样做,但我不确定。
【解决方案3】:

我最终检查了 Url 中是否存在 ReturnUrl,并在 Global.asax 的 EndRequest 阶段将其替换为 RawUrl。现在这对我有用...

这个blog post 帮我设置了它。

protected void Application_EndRequest(object sender, EventArgs e)
{
    string redirectUrl = this.Response.RedirectLocation;
    if (!this.Request.RawUrl.Contains("ReturnUrl=") && !string.IsNullOrEmpty(redirectUrl))
    {
        this.Response.RedirectLocation = Regex.Replace(redirectUrl, "ReturnUrl=(?'url'[^&]*)", delegate(Match m)
        {
            return string.Format("ReturnUrl={0}", HttpUtility.UrlEncode(this.Request.RawUrl));
        }, RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.ExplicitCapture);
    }
}

【讨论】:

    【解决方案4】:

    如果您使用的是 ASP.NET 3.5,请改用 ASP.NET UrlRouting。但是你必须手动检查授权。

    http://chriscavanagh.wordpress.com/2008/03/11/aspnet-routing-goodbye-url-rewriting/

    【讨论】:

    • 感谢您提供信息,但我使用的是 2.0,无法更改所有内容以使用路由...
    猜你喜欢
    • 1970-01-01
    • 2011-11-26
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-08
    相关资源
    最近更新 更多