5

J'ai un dossier avec plusieurs pages .aspx dont je veux limiter l'accès. J'ai ajouté web.config à ce dossier avec <deny users="?"/>.Comment gérer élégamment ReturnUrl lorsque vous utilisez UrlRewrite dans ASP.NET 2.0 WebForms

Le problème est que ReturnUrl est généré automatiquement avec le chemin d'accès physique au fichier .aspx pendant que j'utilise UrlRewrite.

Existe-t-il un moyen de manipuler ReturnUrl sans vérifier et rediriger manuellement l'authentification? Est-il possible de définir ReturnUrl à partir de code-behind ou de web.config?

EDIT: L'application utilise ASP.NET 2.0 WebForms. Je ne peux pas utiliser le routage 3.5.

EDIT 2: Il semble que le code d'état 401 n'est jamais capturé. Il renvoie 302 pour la page protégée et redirige vers la page de connexion avec ReturnUrl. Il ne renvoie pas 401 pour la page protégée. Hmm ... Intéressant ... Ref: http://msdn.microsoft.com/en-us/library/aa480476.aspx

Cela rend les choses plus difficiles ... Il se peut que je doive écrire des règles de mappage de réécriture inverse pour regex match ReturnUrl et le remplacer si elle ne renvoie pas 401 ... Si elle renvoie 401 Je peux définir RawUrl sur Response.RedirectLocation ou remplacer ReturnUrl par RawUrl.

Quelqu'un d'autre a d'autres idées?

+0

Quelqu'un d'autre avec d'autres suggestions? –

Répondre

1

J'ai fini par vérifier l'existence de ReturnUrl dans l'URL et le remplacer par RawUrl dans l'étape EndRequest de Global.asax. Cela fonctionne pour moi pour l'instant ...

Cette blog post m'a aidé à le configurer.

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

Check it out. J'espère que cela t'aides.

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

Merci. Je vais essayer celui-ci. –

+0

Il n'y a aucune chance d'intercepter entre remplacer ReturnUrl avec RawUrl. –

+0

Le code d'état 401 n'est jamais capturé ... Il va à la page protégée (302) -> login avec ReturnUrl (200). –

1

Créer l'adaptateur de commande suivante pour réécrire la balise form avec l'attribut pour l'action. J'ai utilisé cette application ASP.NET 2.0 en conjonction avec le correcteur d'URL Intelligencia. Je l'ai obtenu à partir de ce blog post from the Gu.

Mettez cette classe dans votre dossier 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); 
    } 
} 

Ensuite, créez ce fichier .browser dans votre dossier App_Browsers:

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

On dirait que celui-ci s'occupe de l'URL de la page en postback.Ce que je recherche, c'est l'URL de réécriture propre pour la chaîne de requête ReturnUrl générée automatiquement lorsque vous cliquez sur une page restreinte non authentifiée. –

+0

Je crois qu'il devrait le faire aussi, mais je ne suis pas sûr. – craigmoliver