Question

J'utilise un HttpModule pour réécrire les URL sur un site multilingue. Dans le HttpModule, j'ajoute un gestionnaire pour l'événement BeginRequest et recherche la première partie du chemin qui contient le nom de la culture.

Par exemple, /fr-ca/index.aspx sera réécrit dans /index.aspx et définira la culture du fil et la culture ui sur 3084. Cela fonctionne correctement.

Entrez l'authentification par formulaire. L’authentification par formulaire fonctionne toujours bien avec l’URL non mappée, mais si l’utilisateur est non autorisé, il sera redirigé vers le loginUrl comme défini dans la section d’authentification du web.config, et inclura le paramètre? ReturnUrl = querystring pour gérer la redirection vers le page une fois l'utilisateur authentifié.

Il y a deux problèmes ici si l'utilisateur demande une page dans une langue autre que celle par défaut:

  1. loginUrl ignore le chemin avant sa réécriture
  2. Le paramètre ReturnUrl a également ignoré le chemin brut.

Cela équivaut à Request.Url.PathAndQuery au lieu de Request.RawUrl.

Je ne peux pas me lancer dans le pipeline à la place de l'événement AuthorizeRequest car je devrais alors me protéger contre toutes les valeurs de culture possibles, car j'utilise un seul fichier web.config avec plusieurs chemins d'emplacement. Cela ne résout pas non plus le premier problème.

J'ai examiné le module FormsAuthenticationModule dans le réflecteur et je vois où je pourrais le changer pour résoudre les problèmes n ° 1 et n ° 2, mais il est bien sûr scellé.

J'ai aussi beaucoup navigué, mais je ne vois pas de solutions réalisables.

FormsAuthenticationModule recherche un en-tête 401 généré dans UrlAuthorizationModule. Si vous recherchez le référent (qui est vide) sur la page loginUrl, il vous confirmera que.

Avez-vous des idées?

EDIT # 1

J'utilise IIS 6 et IIS 7 n'est pas une option.

EDIT n ° 2

La page de connexion ne sélectionnait pas la culture / interface utilisateur par défaut, car lorsque j'ai généré la ressource locale (mode Création: Outils > Générer une ressource locale), l'EDI a ajouté les éléments suivants à la directive de page:

culture = " auto " meta: resourcekey = " PageResource1 " uiculture = " auto "

Faites attention à cela dans vs.net 2008! Au moins, cela résout l’un des problèmes liés au fait que la culture par défaut n’est pas référencée, mais que les numéros 1 et 2 restent en suspens.

EDIT 3

J'espérais pouvoir accéder à l'un des événements de pipeline pour effectuer ma propre redirection, mais dans la méthode Reflecting of System.Web.Security.UrlAuthorizationModule OnEnter, j'ai appris qu'une fois l'en-tête 401 défini, la méthode appelle l'application. CompleteRequest, qui, comme vous pouvez le deviner, nous amène directement à l'événement EndRequest. C’est ce que le module FA saute dans la redirection, et j’ai peur de ne pouvoir sauter devant pour faire ma propre redirection! Je suis surpris qu'il n'y ait pas plus de gens qui rencontrent ce problème, ou peut-être qu'ils ne se soient pas encore manifestés.

Exemple:

J'ai une section membre dans le dossier physique / membres / qui est protégée par l'authentification par formulaires.

Dans le web.config, j'ai:

<authentication mode="Forms">
  <forms loginUrl="~/members/login.aspx" timeout="40" />
</authentication>

et ...

  <location path="members">
      <system.web>
          <authorization>
              <deny users="?" />
              <allow roles="Members" />
              <deny users="*" />
          </authorization>
      </system.web>
  </location>

Lorsqu'un utilisateur non authentifié demande la page d'index de / members /, il est redirigé vers le loginUrl à partir de la section d'authentification ci-dessus par le FormsAuthenticationModule. Il ajoute également le paramètre? ReturnUrl à la page demandée.

Cela fonctionne très bien si un utilisateur navigue sur le site Web en utilisant la culture par défaut, mais mon HttpModule définit la culture en fonction de la présence d'un nom de culture dans la première partie du chemin.

Ainsi, /fr-ca/members/index.aspx est réécrit dans /members/index.aspx et définit la culture / ui culture en français canadien. Malheureusement, le FormsAuthenticationModule envoie l’utilisateur à la page loginUrl avec l’URL réécrite, pas l’original. Ainsi, le paramètre de culture est perdu et l'URL de redirection est incorrecte.

J'espère queaide @Greg

Était-ce utile?

La solution

Ok, le problème est résolu.

Il s’avère que la clé efface les httpModules de machine.config, ajoute mon httpModule personnalisé, puis rajoute les httpModules par défaut requis. Cela a permis à mon httpModule personnalisé de sauter dans l'événement EndRequest avant le FormsAuthenticationHttpModule.

<httpModules>
    <clear/>
    <!-- custom -->
    <add name="LocalizationHttpModule" type="LocalizationHttpModule"/>
    <!-- add back defaults, exlude PassportAuthentication, AnonymousIdentification, Profile -->
    <add name="OutputCache" type="System.Web.Caching.OutputCacheModule" />
    <add name="Session" type="System.Web.SessionState.SessionStateModule" />
    <add name="WindowsAuthentication" type="System.Web.Security.WindowsAuthenticationModule" />
    <add name="FormsAuthentication" type="System.Web.Security.FormsAuthenticationModule" />
    <add name="RoleManager" type="System.Web.Security.RoleManagerModule" />
    <add name="UrlAuthorization" type="System.Web.Security.UrlAuthorizationModule" />
    <add name="FileAuthorization" type="System.Web.Security.FileAuthorizationModule" />

</httpModules> 

Ensuite, dans mon httpModule personnalisé, je me contente de me connecter à EndRequest, de rechercher le code d'état 401 et de le rediriger à ma guise. En gros, je réécris le code de la méthode OnLeave de FormsAuthenticationHttpModule pour répondre à mes besoins.

Public Sub Init(ByVal context As System.Web.HttpApplication) Implements System.Web.IHttpModule.Init

    Dim authentication As AuthenticationSection = WebConfigurationManager.GetSection("system.web/authentication")
    If authentication.Mode = AuthenticationMode.Forms Then
        Me._LoginUrl = authentication.Forms.LoginUrl
        AddHandler context.EndRequest, AddressOf Context_EndRequest
    End If

End Sub

Private Sub Context_EndRequest(ByVal sender As Object, ByVal e As EventArgs)
    Dim application As HttpApplication = DirectCast(sender, HttpApplication)
    Dim context As HttpContext = application.Context

    If (context.Response.StatusCode = &H191) Then                
       ' do custom redirect here
    End If

End Sub

Autres conseils

La seule chose à laquelle je peux penser est de faire la redirection manuellement vers le formulaire de connexion.

1) Autoriser tout accès au répertoire des membres
2) Toutes les pages de l'adhésion héritent directement d'une sous-classe de Page.
3) Dans PreInit (?) De la sous-classe Page, vérifiez si l'utilisateur est membre du rôle d'appartenance.
4) Sinon, créez vous-même l'URL de la page de connexion, y compris le paramètre ReturnURL et redirigez l'utilisateur vers votre URL de connexion.

Vous pourrez peut-être aussi pirater ceci en mettant un tas de < emplacement > sections de votre web.config. ex: < emplacement path = " fr-ca / members " > < authentification > < formulaires loginUrl = " ~ / fr-ca / members / login.aspx " > ... mais je n'en ai aucune idée.

Il y a probablement d'autres moyens de le faire que je ne connais pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top