Ignorar o redirecionamento automático de autenticação de formulários para login, como fazer?

StackOverflow https://stackoverflow.com/questions/35322

Pergunta

Estou escrevendo um aplicativo usando asp.net-mvc, implantando no iis6.Estou usando autenticação de formulários.Normalmente, quando um usuário tenta acessar um recurso sem a devida autorização, quero que ele seja redirecionado para uma página de login.FormsAuth faz isso para mim com bastante facilidade.

Problema:Agora tenho uma ação acessada por um aplicativo de console.Qual é a maneira mais rápida de fazer com que esta ação responda com status 401 em vez de redirecionar a solicitação para a página de login?

Quero que o aplicativo de console seja capaz de reagir a este 401 StatusCode em vez de ser transparente.Também gostaria de manter o padrão, redirecionar solicitações não autorizadas para o comportamento da página de login.

Observação:Como teste, adicionei isso ao meu global.asax e não ignorou a autenticação de formulários:

protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
    HttpContext.Current.SkipAuthorization = true;
}

@Dale e Andy

Estou usando o AuthorizeAttributeFilter fornecido na visualização 4 do MVC.Isso está retornando um HttpUnauthorizedResult.Este resultado está configurando corretamente o statusCode como 401.O problema, pelo que entendi, é que o asp.net está interceptando a resposta (já que está marcada como 401) e redirecionando para a página de login em vez de apenas deixá-la passar.Quero ignorar essa interceptação para determinados URLs.

Foi útil?

Solução

Ok, eu resolvi isso.Fiz um ActionResult personalizado (HttpForbiddenResult) e um ActionFilter personalizado (NoFallBackAuthorize).

Para evitar o redirecionamento, HttpForbiddenResult marca as respostas com o código de status 403.FormsAuthentication não captura respostas com este código, portanto o redirecionamento de login é efetivamente ignorado.O filtro NoFallBackAuthorize verifica se o usuário está autorizado de forma semelhante ao filtro Authorize incluído.A diferença é que retorna HttpForbiddenResult quando o acesso é negado.

O HttpForbiddenResult é bastante trivial:

public class HttpForbiddenResult : ActionResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        context.HttpContext.Response.StatusCode = 0x193; // 403
    }
}

Não parece ser possível ignorar o redirecionamento da página de login no FormsAuthenticationModule.

Outras dicas

Pode ser um erro (e pode nem funcionar), mas na sua página de login veja se Request.QueryString["ReturnUrl"] != null e se assim for definido Response.StatusCode = 401.

Lembre-se de que você ainda precisará autenticar seu aplicativo de console de alguma forma.Você não obtém autenticação básica HTTP gratuitamente:você precisa criar o seu próprio, mas há muitas implementações por aí.

Você escreveu seu próprio atributo FormsAuth para a ação?Nesse caso, no método OnActionExecuting, você recebe o FilterExecutingContext.Você pode usar isso para devolver o código 401.

public class FormsAuth : ActionFilterAttribute
{
    public override void OnActionExecuting(FilterExecutingContext filterContext)
    {
        filterContext.HttpContext.Response.StatusCode = 401;
        filterContext.Cancel = true;
    }
}

Isso deve funcionar.Não tenho certeza se você escreveu o atributo FormsAuth ou se o obteve de outro lugar.

Ainda não usei o AuthorizeAttribute que vem na Visualização 4.Eu criei o meu próprio, porque uso o framework MVC desde o primeiro CTP.Dei uma olhada rápida no atributo no refletor e ele está fazendo o que mencionei acima internamente, exceto que eles usam o equivalente hexadecimal de 401.Precisarei procurar mais adiante na chamada, para ver onde a exceção foi detectada, porque é mais do que provável que seja onde eles estão fazendo o redirecionamento.Esta é a funcionalidade que você precisará substituir.Não tenho certeza se você pode fazer isso ainda, mas postarei de volta quando encontrar e lhe darei uma solução alternativa, a menos que Haacked veja isso e publique ele mesmo.

Pesquisei no Google e foi isso que descobri:


    HttpContext.Current.Response.StatusCode = 401;

Não tenho certeza se funciona ou não, não testei.De qualquer forma, vale a pena tentar, certo?:)

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