Как элегантно обрабатывать ReturnUrl при использовании UrlRewrite в веб-формах ASP.NET 2.0 - PullRequest
5 голосов
/ 01 декабря 2009

У меня есть папка с несколькими ASPX-страницами, доступ к которым я хочу ограничить. Я добавил web.config в эту папку с <deny users="?"/>.

Проблема в том, что ReturnUrl автоматически генерируется с физическим путем к файлу .aspx, пока я использую UrlRewrite.

Есть ли способ манипулировать ReturnUrl без ручной проверки подлинности и перенаправления? Есть ли способ установить ReturnUrl из-за кода или из web.config?

РЕДАКТИРОВАТЬ : приложение использует веб-формы ASP.NET 2.0. Я не могу использовать 3.5 маршрутизации.

РЕДАКТИРОВАТЬ 2 : Кажется, что код состояния 401 никогда не фиксируется. Он возвращает 302 для защищенной страницы и перенаправляет на страницу входа с ReturnUrl. Он не возвращает 401 для защищенной страницы. Хм ... Интересно ... Ссылка: http://msdn.microsoft.com/en-us/library/aa480476.aspx

Это усложняет ситуацию ... Возможно, мне придется написать правила сопоставления перезаписи, чтобы регулярное выражение соответствовало ReturnUrl, и заменить его, если оно не возвращает 401 ... Если оно возвращает 401, я могу либо установить RawUrl в Response.RedirectLocation или замените ReturnUrl на RawUrl.

У кого-нибудь есть еще идеи?

Ответы [ 4 ]

1 голос
/ 07 декабря 2009

В итоге я проверил существование ReturnUrl в URL и заменил его на RawUrl на этапе EndRequest в Global.asax. Это работает для меня сейчас ...

Это сообщение в блоге помогло мне настроить его.

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);
    }
}
1 голос
/ 03 декабря 2009

Проверьте это. Надеюсь, это поможет.

#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>
1 голос
/ 04 декабря 2009

Создайте следующий адаптер элемента управления, чтобы переписать тег формы с атрибутом для действия. Я использовал это приложение ASP.NET 2.0 в сочетании с Intelligencia переписчиком URL. Я получил это от этого сообщения в блоге от Гу .

Поместите этот класс в папку 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);
    }
}

Затем создайте этот файл .browser в папке App_Browsers:

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.HtmlControls.HtmlForm" adapterType="FormRewriterControlAdapter" />
    </controlAdapters>
  </browser>
</browsers>
0 голосов
/ 01 декабря 2009

Если вы используете ASP.NET 3.5, используйте вместо этого ASP.NET UrlRouting. Но вы должны проверить авторизацию вручную.

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

...