Pregunta

Estoy usando un HttpModule para reescribir las URL en un sitio multilingüe. En el HttpModule, agrego un controlador para el evento BeginRequest y busco la primera parte de la ruta que contiene el nombre de la cultura.

Por ejemplo, /fr-ca/index.aspx se reescribirá a /index.aspx y establecerá la cultura del hilo y la cultura de la interfaz de usuario en 3084. Esto funciona bien.

Ingrese la autenticación de formularios. La autenticación de formularios todavía funciona bien con la URL no asignada, pero si el usuario no está autorizado, redirigirá a loginUrl como se establece en la sección de autenticación de web.config e incluirá el parámetro? ReturnUrl = querystring para manejar la redirección de regreso a la solicitada página una vez que el usuario se autentica.

Hay dos problemas aquí si el usuario solicita una página en un idioma que no sea el predeterminado:

  1. loginUrl ignora la ruta antes de reescribirse
  2. El parámetro ReturnUrl también ignoró la ruta sin formato.

Es equivalente a Request.Url.PathAndQuery en lugar de Request.RawUrl.

No puedo saltar a la tubería en el evento AuthorizeRequest porque tendría que protegerme contra todos los valores culturales posibles, porque estoy usando un archivo web.config con múltiples rutas de ubicación. Esto tampoco soluciona el primer problema.

Revisé el módulo FormsAuthenticationModule en el reflector y veo dónde podría cambiarlo para resolver el n. ° 1 y n. ° 2, pero por supuesto está sellado.

También he navegado mucho, pero no veo ninguna solución viable.

FormsAuthenticationModule está buscando un encabezado 401 que se genera en UrlAuthorizationModule. Si busca el referente (que está vacío) en la página loginUrl, lo confirma.

¿Alguna idea?

EDITAR # 1

Estoy usando IIS 6, e IIS 7 no es una opción.

EDITAR # 2

La página de inicio de sesión no estaba recogiendo la cultura ui cultura predeterminada porque cuando generé el recurso local (vista de diseño: Herramientas > Generar recurso local), el IDE agregó lo siguiente a la directiva de la página:

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

¡Tenga cuidado con esto en vs.net 2008! Al menos esto resuelve uno de los problemas con la cultura predeterminada que no se hace referencia, pero el número 1 y el número 2 siguen pendientes.

EDITAR 3

Esperaba poder saltar a uno de los eventos de canalización para hacer mi propia redirección, pero en Reflejando el método System.Web.Security.UrlAuthorizationModule OnEnter, aprendí que una vez que se establece el encabezado 401, el método llama a la aplicación. CompleteRequest, que como puedes adivinar, nos lleva directamente al evento EndRequest. ¡Esto es lo que el módulo FA salta al hacer la redirección, y me temo que no puedo saltar al frente para hacer mi propia redirección! Me sorprende que no haya más personas que se encuentren con este problema, o tal vez aún no hayan intervenido.


Ejemplo:

Tengo una sección de miembro en la carpeta física / members / que está protegida por autenticación de formularios.

En web.config, tengo:

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

y ...

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

Cuando un usuario no autenticado solicita la página de índice de / members /, FormsAuthenticationModule redirige a loginUrl desde la sección de autenticación anterior. También agrega el parámetro? ReturnUrl con la página solicitada.

Esto funciona bien si un usuario navega por el sitio web utilizando la cultura predeterminada, pero mi HttpModule establece la cultura en función de la presencia de un nombre de cultura en la primera parte de la ruta.

Entonces, /fr-ca/members/index.aspx se reescribe en /members/index.aspx y establece la cultura / ui culture en francés canadiense. Desafortunadamente, FormsAuthenticationModule envía al usuario a la página loginUrl con la url reescrita, no la original. Por lo tanto, se pierde la configuración de cultura y la URL de redireccionamiento es incorrecta.

Espero queayuda a @Greg

¿Fue útil?

Solución

Ok, problema resuelto.

Resulta que la clave estaba borrando machine.config httpModules, agregando mi httpModule personalizado y luego volviendo a agregar los httpModules predeterminados requeridos. Esto permitió que mi httpModule personalizado saltara al evento EndRequest antes de 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> 

Luego, en mi httpModule personalizado, solo accedo a EndRequest, busco el código de estado 401 y redirijo como lo deseo. Básicamente, estoy reescribiendo el código del método FormsAuthenticationHttpModule OnLeave para satisfacer mis necesidades.

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

Otros consejos

Lo único que se me ocurre es hacer la redirección al formulario de inicio de sesión manualmente.

1) Permitir todo el acceso al directorio de miembros
2) Todas las páginas de la membresía heredan directamente de una subclase de Página.
3) En PreInit (?) De la subclase de Página, verifique si el usuario es miembro del rol de miembro.
4) Si no, cree la URL de la página de inicio de sesión usted mismo, incluido el parámetro ReturnURL y redirija al usuario a su URL de inicio de sesión.

También podrías piratear esto poniendo un montón de < ubicación > secciones en su web.config. ej: < ubicación ruta = " fr-ca / members " > < autenticación > < formularios loginUrl = " ~ / fr-ca / members / login.aspx " > ... pero realmente no tengo idea.

Probablemente hay otras formas de hacerlo con las que no estoy familiarizado.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top