Pergunta

Eu estou usando um HttpModule para reescrever as URLs em um site multi-lingual. No HttpModule, eu estou adicionando um manipulador para o evento BeginRequest, e olhando para a primeira parte do caminho que contém o nome de cultura.

Por exemplo, /fr-ca/index.aspx será reescrito para /index.aspx e definir a cultura do thread e cultura ui de 3084. Essa multa funciona.

Entre autenticação de formulários. autenticação de formulários ainda funciona bem com a url não mapeado, mas se o usuário não é autorizado, ele irá redirecionar para a loginUrl como conjunto na seção de autenticação do web.config, e incluem a? ReturnUrl = querystring parâmetro para lidar com o redirecionamento de volta para o pedido página uma vez que o usuário é autenticado.

Há dois problemas aqui se o usuário solicita uma página em um idioma diferente do padrão:

  1. O loginUrl ignora o caminho antes de ser reescrito
  2. O parâmetro ReturnUrl também ignorou o caminho matéria.

É equivalente a Request.Url.PathAndQuery vez de Request.RawUrl.

Eu não pode saltar para o gasoduto no evento AuthorizeRequest vez porque então eu teria que protege contra todos os valores da cultura possíveis, porque eu estou usando um arquivo web.config com vários caminhos localização. Isso também não resolver o primeiro problema.

Eu tenho ido através do FormsAuthenticationModule no refletor e vejo onde eu poderia mudá-lo para resolver # 1 e # 2, mas é claro selado.

Eu também tenho navegado em torno de um monte, mas eu não consigo ver nenhum soluções viáveis.

O FormsAuthenticationModule está verificando um cabeçalho 401 que é gerado em UrlAuthorizationModule. Se você olhar para a referência (que está vazia) na página loginUrl confirma isso.

Qualquer pensamento?

EDIT # 1

Estou usando o IIS 6 e IIS 7 não é uma opção.

EDIT # 2

A página de login não estava pegando a cultura cultura padrão / ui porque quando eu gerado o recurso local (exibição de design: Ferramentas> Gerar Resource Local), o IDE adicionou o seguinte à diretiva de página:

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

Tenha cuidado com isso em vs.net 2008! Pelo menos isso resolve um dos problemas com a cultura padrão não está sendo referenciado, mas # 1 e # 2 ainda estão pendentes.

EDIT 3

Eu esperava que eu poderia saltar para um dos eventos de dutos para fazer minha própria redirecionamento, mas em Refletindo a System.Web.Security.UrlAuthorizationModule OnEnter método, eu aprendi que uma vez que o cabeçalho 401 é definido, o método chama aplicação. CompleteRequest, que como você pode imaginar, leva-nos à direita para o evento EndRequest. Isto é o que o módulo FA salta para o fazer o redirecionamento, e eu tenho medo eu não posso pular na frente para fazer a minha própria redirecionamento! Estou surpreso não há mais pessoas que vêm em toda esta questão, ou talvez eles não tenham opinou ainda.


Exemplo:

Eu tenho secção de um membro no físico pasta / membros / que é protegido por autenticação de formulários.

No web.config, eu tenho:

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

e ...

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

Quando um usuário não autenticado solicita a página Index of / membros /, eles são redirecionados para o loginUrl da seção de autenticação acima pela FormsAuthenticationModule. Ele também acrescenta o? ReturnUrl parâmetro com a página solicitada.

Isso funciona muito bem se um usuário estiver navegando no site usando a cultura padrão, mas meu HttpModule define a cultura com base na presença de um nome de cultura na primeira parte do caminho.

Assim, /fr-ca/members/index.aspx é reescrito para /members/index.aspx e conjuntos da cultura / cultura ui para francês canadense. Unforunately, o FormsAuthenticationModule envia o usuário para a página loginUrl com a url reescrito, não o original. Assim, a definição de cultura é perdida eo url redirecionamento está incorreto.

Espero que ajude @ Greg

Foi útil?

Solução

Ok, problema resolvido.

Acontece que a chave estava limpando o machine.config httpModules, acrescentando meu costume httpModule, em seguida, adicionar de volta o necessário padrão httpModules. Isto permitiu que meu costume httpModule para saltar para o evento EndRequest antes do 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> 

Então, em meu costume httpModule, eu apenas tocar para o EndRequest, olhar para o código de status 401, e redirecionamento como eu desejo. Basicamente eu estou reescrevendo o código a partir do método FormsAuthenticationHttpModule OnLeave para atender às minhas necessidades.

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

Outras dicas

Sobre a única coisa que posso pensar é fazer o redirecionamento para o formulário de login manualmente.

1) Permitir todo o acesso ao diretório de membros
2) Todas as páginas na composição diretamente herdar de uma subclasse da página.
3) Em PreInit (?) Da página subclasse, verificar para ver se o usuário é membro da função de membro.
4) Se não, construção URL da página de login si, incluindo parâmetro ReturnURL e usuário redirecionamento para o URL do login.

Você pode ser também capaz de cortar isso colocando um um monte de seções em seu web.config. ex:. ... mas eu realmente não tenho idéia

Há provavelmente outras maneiras de fazer isso que não estou familiarizado.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top