在 ASP.NET 2.0 WebForms 中使用 UrlRewrite 时如何优雅地处理 ReturnUrl

发布于 2024-08-13 06:51:12 字数 764 浏览 10 评论 0原文

我有一个包含多个 .aspx 页面的文件夹,我想限制其访问。我已使用 将 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。

还有其他人有其他想法吗?

I have a folder with multiple .aspx pages that I want to restrict access to. I have added web.config to that folder with <deny users="?"/>.

The problem is that ReturnUrl is auto-generated with physical path to the .aspx file while I'm using UrlRewrite.

Is there a way to manipulate ReturnUrl without doing manual authentication check and redirection? Is there a way to set ReturnUrl from code-behind or from web.config?

EDIT: The application is using ASP.NET 2.0 WebForms. I cannot use 3.5 routing.

EDIT 2: It seems like 401 status code is never captured. It returns 302 for protected page and redirects to login page with ReturnUrl. It does not return 401 for protected page. Hmm... Interesting... Ref: http://msdn.microsoft.com/en-us/library/aa480476.aspx

This makes things harder... I might have to write reverse rewrite mapping rules to regex match ReturnUrl and replace it if it doesn't return 401... If it does return 401 I can either set RawUrl to Response.RedirectLocation or replace ReturnUrl with RawUrl.

Anyone else have any other ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

谈情不如逗狗 2024-08-20 06:51:12

一探究竟。希望这有帮助。

#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>

Check it out. Hope this helps.

#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>
爱的故事 2024-08-20 06:51:12

创建以下控件适配器以使用 for action 属性重写表单标签。我将这个 ASP.NET 2.0 应用程序与 Intelligencia url 重写器结合使用。我从这个 来自 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>

Create the following control adapter to rewrite the form tag with the for the action attribute. I used this a ASP.NET 2.0 app in conjunction with the Intelligencia url rewriter. I got it from this blog post from the Gu.

Put this class in your App_Code folder:

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);
    }
}

Then, create this .browser file in your App_Browsers folder:

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.HtmlControls.HtmlForm" adapterType="FormRewriterControlAdapter" />
    </controlAdapters>
  </browser>
</browsers>
笑脸一如从前 2024-08-20 06:51:12

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

这个 博客文章 帮助我进行了设置。

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);
    }
}

I ended up checking for existence of ReturnUrl in the Url and replacing it with RawUrl in EndRequest stage in Global.asax. This works for me for now...

This blog post helped me setting it up.

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);
    }
}
狠疯拽 2024-08-20 06:51:12

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

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

If you are using ASP.NET 3.5, use ASP.NET UrlRouting instead. But you must check the authorization manualy.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文