Pergunta

Alguns antecedentes:Nosso cliente queria que uma série de ações retornassem à ação anterior quando concluídas.Por exemplo, se ele estava em uma visualização de lista de objetos e clicou no botão "criar novo objeto", ele desejaria retornar à visualização de lista após preencher e salvar o formulário ou após cancelar a ação.Nós o implementamos imitando o ReturnUrl comportamento usado com tentativas de acesso não autorizado (adicionando o endereço atual como um parâmetro de consulta codificado em URL).

O problema:Se eu não estiver autorizado (ou em outras palavras, não estiver logado) e tentar acessar uma ação que exija isso, sou redirecionado para a página de login (como deveria) e o URL atual é colocado em ReturnUrl parâmetro.No entanto, quando o endereço atual já contém ReturnUrl parâmetro de consulta, não estou sendo redirecionado para lugar nenhum e, em vez disso, recebo uma página em branco.Existe alguma razão para isso acontecer?

O resultado esperado seria ser redirecionado para a tela de login com o URL atual (versão codificada em URL) colocado no ReturnUrl param (independentemente de o URL atual conter seu próprio ReturnUrl parâmetro ou não)

Existe alguma maneira de fazer funcionar conforme o esperado?Claro, em teoria eu poderia renomear o parâmetro "ReturnUrl" (em minhas próprias ações) para outra coisa, mas já usamos esse parâmetro em tantos lugares que renomeá-los não será uma tarefa fácil.Além disso, eu realmente não entendo por que isso não funciona.

P.S.O problema só ocorre se eu nomear o parâmetro ReturnUrl, se é returnUrl Tudo funciona como deveria.


Editar:Esta questão foi anteriormente chamada:O acesso não autorizado a ações restritas não retorna nada se o URL contiver um parâmetro chamado ReturnUrl.Alterei o título para facilitar a compreensão.


Editar:Esta pergunta pode ser uma duplicata de A solicitação não autorizada não redireciona para a página de login com o parâmetro de string de consulta returnUrl.Terei que investigar mais a fundo se a solução fornecida resolve meu problema ou não. Atualizar:O texto é semelhante, mas afinal o problema é diferente, portanto não é uma duplicata.

Foi útil?

Solução

Isso foi uma grande dor de cabeça para consertar, mas consegui fazer isso.Na busca para descobrir por que o redirecionamento para login falha em alguns URLs, tive que responder a uma pergunta importante.O que é realmente responsável por fazer o redirecionamento e como posso substituir isso?

Esse artigo me colocou no caminho certo (o responsável pelo redirecionamento foi o [Authorize] filtro) e comecei a procurar uma solução.Depois de um pouco de pesquisa encontrei esse filtro de autorização personalizado simples.É claro que ele não fez o que eu queria imediatamente (e o que eu quero é basicamente que a autorização funcione normalmente, mas não quebre os URLs que contêm ReturnUrl param), então alterei o código e consegui isso:

public class Authorize2 : AuthorizeAttribute
{
    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        // 1. Get the default login url that was declared in web.config
        string returnUrl = FormsAuthentication.LoginUrl;
        // 2. Append current url as a return url to the login url
        returnUrl += "?ReturnUrl=" + HttpUtility.UrlEncode(HttpContext.Current.Request.Url.PathAndQuery);
        // 3. ...
        // 4. Profit
        filterContext.Result = new RedirectResult(returnUrl);
    }
}

Depois de escrever este trecho de código, passei mais uma hora tentando descobrir por que ele não funciona (pontos de interrupção dentro do HandleUnauthorizedRequest nunca foram atingidos).Então eu encontrei esse site e de repente fez sentido.Um colega meu adicionou um global Authorize filtrar para todas as ações por qualquer motivo e meu próprio filtro personalizado nunca foi solicitado a autorizar nada (\App_Start\FilterConfig.cs).Depois de remover essa linha (eventualmente terei que colocar meu filtro personalizado em seu lugar), o código acima funcionou perfeitamente.

De certa forma, a questão ainda está em aberto, quero dizer, ainda é um mistério por que o Authorize falha para esses URLs.A resposta a essa pergunta está, sem dúvida, em System.Web.Mvc.AuthorizeAttribute código-fonte, mas por enquanto estou satisfeito apenas em fazê-lo funcionar corretamente.

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