Zammad: Respostas HTTP 401 causando problemas com autenticação básica

Criado em 24 mar. 2020  ·  12Comentários  ·  Fonte: zammad/zammad

Infos:

  • Versão Zammad usada: 3.2.0
  • Método de instalação (fonte, pacote, ..): Da fonte usando Ruby 2.5.5, atrás de nginx rproxy.
  • Sistema operacional: Ubuntu 18.04.4 LTS (biônico)
  • Banco de dados + versão: postgres 9.5.21
  • Versão do Elasticsearch: 5.6.16
  • Navegador + versão: Google Chrome 80.0.3987.132

Comportamento esperado:

Zammad integra-se perfeitamente com uma camada de autenticação básica . Portanto, o código de status "HTTP 401 Unauthorized" nunca é usado. Como alternativa, o código de status 403 seria uma substituição adequada.

Comportamento real:

No geral, o Zammad não tem muitos problemas quando combinado com autenticação básica. Mas existem alguns casos em que uma solicitação é respondida com um código de status 401 e o usuário atual é forçado a inserir novamente suas credenciais de autenticação básicas.

A base de código pode ser pesquisada facilmente pelo status 401 (ou unauthorized ):
https://github.com/zammad/zammad/search?l=Ruby&q=%3Aunauthorized

Passos para reproduzir o comportamento:

  • Configure uma instância Zammad e coloque-a atrás da autenticação básica

ENTÃO

  • Tente fazer login com credenciais erradas
  • O aplicativo renderiza uma página com o código de status 401 e força você a inserir novamente as credenciais de autenticação básicas

OU

  • Crie um tíquete atribuído a um grupo onde a pessoa 1 tem acesso
  • A pessoa 1 interage com aquele tíquete
  • Mova esse tíquete para outro grupo que não seja acessível para a pessoa 1
  • A pessoa 1 ainda verá uma solicitação 401 para o tíquete acima em sua visão geral do Zammad, que o desconectará do auth básico

Sim, tenho certeza que isso é um bug e nenhuma solicitação de recurso ou uma questão geral.

API bug verified

Comentários muito úteis

Ei pessoal! Obrigado pelas informações e descrições valiosas. Eu li o RFC e ainda estava um pouco confuso sobre as diferenças entre 401 e 403. No entanto, encontrei essa ótima explicação no StackOverflow. Citar:

Há um problema com 401 Unauthorized, o código de status HTTP para erros de autenticação. E é isso mesmo: é para autenticação, não para autorização.

Isso traz a questão. Zammad usa 401 para authorization erros. Isso é tecnicamente errado e, portanto, um bug. Vou reabrir o problema.

No entanto, precisamos verificar o impacto. Suponho que seja uma mudança significativa por causa de todas as implementações e consumidores de API por aí.
Meu plano atual é descontinuar o uso moderado de 401 authorization com Zammad 3.4, descontinuá-lo totalmente com 3.5 (ou 3.6) e mudar para 403.
Precisamos discutir isso mais internamente.

Mais reflexões sobre esse alguém?

Todos 12 comentários

Por favor, atualize seu primeiro artigo para manter suas informações exatas de instalação - "qualquer" não é realmente adequado neste ponto - desculpe. :)

Além disso, forneça a configuração completa do servidor da web (e nos informe qual você está usando). No momento, cheira um pouco a uma questão técnica, mas gostaria de ter certeza absoluta. Porém, para isso preciso de tudo. ;)

Obrigado.

Oi de novo,
Eu atualizei a descrição do problema - desculpe pela falta dela inicial!
Melhor

Obrigado pela atualização. A configuração do seu servidor web é a nossa configuração padrão estendida por autenticação básica? Você se importaria de fornecer essa configuração de vhost também? Só para ter certeza de que não estou perdendo nada.

Obrigado!

Sim, é basicamente apenas Zammad Default config + Basic Auth. Aqui está a configuração do vhost:

auth_basic 'Restricted: general basic auth';
auth_basic_user_file /etc/.htpasswd.d/zammad;
location /ws {
    proxy_pass  http://zammad_ws;
    proxy_redirect  off;
    proxy_hide_header X-Powered-By;
    proxy_set_header  Host              $host;
    proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_set_header  X-Real-IP         $remote_addr;
    proxy_set_header  X-Forwarded-Host  $host;
    proxy_set_header  X-Forwarded-Port  443;
    proxy_set_header CLIENT_IP $remote_addr;
    proxy_read_timeout 86400;
    proxy_http_version 1.1;
    proxy_set_header  Upgrade           $http_upgrade;
    proxy_set_header  Connection        "upgrade";
    proxy_max_temp_file_size  0;
    error_page 502 503 504 =503 @fallback;
}
location / { 
    try_files $uri @proxy;
}
location <strong i="6">@proxy</strong> { 
    proxy_pass  http://zammad;
    proxy_redirect  off;
    proxy_hide_header X-Powered-By;
    proxy_set_header  Host              $host;
    proxy_set_header  X-Forwarded-For   $proxy_add_x_forwarded_for;
    proxy_set_header  X-Forwarded-Proto https;
    proxy_set_header  X-Real-IP         $remote_addr;
    proxy_set_header  X-Forwarded-Host  $host;
    proxy_set_header  X-Forwarded-Port  $server_port;
    proxy_http_version 1.1;
    proxy_set_header  Upgrade           $http_upgrade;
    proxy_set_header  Connection        "upgrade";
    proxy_max_temp_file_size  0;
    proxy_set_header CLIENT_IP $remote_addr;
    error_page 502 503 504 =503 @fallback;
}

Nós examinamos isso novamente.
Nossa suposição (como Michael escreveu) seria não retornar um HTTP 401 (o que faz o navegador acreditar que as credenciais de autenticação básicas fornecidas estão incorretas), mas retornar HTTP 403 proibido.

Se eu vi corretamente, isso significaria

app / controllers / application_controller / handles_errors.rb # L39
respond_to_exception(e, :unauthorized)

deve ser substituído por
respond_to_exception(e, :forbidden)

A RFC diz que os navegadores devem se comportar de maneira diferente (https://tools.ietf.org/html/rfc7231#section-6.5.3): "Se as credenciais de autenticação forem fornecidas na solicitação, o servidor as considera insuficientes para conceder acesso. O cliente DEVE NÃO repita automaticamente a solicitação com as mesmas credenciais. "

Porém, tivemos o mesmo problema em outro projeto na semana passada e 403 trabalhos.
Se você não encontrar outros problemas para devolver um 403, podemos emitir um PR.

Melhor

Desculpe demorar tanto.
Observe que este não é um problema relacionado ao Zammad (baseado em aplicativo), mas um "problema de back-end" em seu nginx.

As solicitações de autenticação para a autenticação básica nunca chegam ao Zammad como aplicativo, mas já termina (e é verificado por) seu nginx ou qualquer outro servidor da web que você use.

Portanto, alterar o código-fonte, em minha opinião, não resolve o seu problema.
Tecnicamente, um 401 não autorizado está correto pelo que posso dizer (embora eu entenda que você gostaria de um 403).

Veja também:
https://serverfault.com/questions/616770/nginx-auth-basic-401-htpasswd

A propósito:
Apenas para verificar, eu comentei completamente as partes do proxy Zammad para garantir que o backend do Zammad não possa responder. O resultado com 401 é o mesmo e, portanto, falha do nginx. :)

Fechando porque isso não é um bug, mas uma questão técnica.

Olá @MrGeneration ,
obrigado por olhar para isso.

Embora eu entenda que esse problema parece estar fora do escopo do aplicativo Zammad, ainda acho que é causado por ele (e não pelo Ngnix). Vou tentar explicar o porquê:

Vamos supor que nosso ngnix _não_ esteja configurado para usar autenticação básica. Nesse caso, nós dois concordamos que o aplicativo Zammad ("por trás" do ngnix) funciona bem.

Agora, habilitamos a autenticação básica adicionando a configuração indicada acima ao nosso ngnix. Observe que mesmo agora, quase tudo ainda funciona conforme o esperado - incluindo as autenticações (login básico e Zammad) e o próprio aplicativo Zammad.

O problema que tentei descrever anteriormente é causado às vezes mais tarde (por Zammad!), Quando o aplicativo renderiza uma página com o código de status 401. Nesse caso, _qualquer servidor da web_ com autenticação básica habilitada é forçado a fazer o seu logout.

Eu concordo que semanticamente falando 401 soa "certo" neste caso. Tecnicamente falando, ele causa problemas inevitáveis ​​com a autenticação básica e deve ser substituído pelo 403.
Abra novamente este problema, pois ele também pode afetar a experiência do usuário do aplicativo Zammad para muitos usuários.

@thorsteneckel qual a sua opinião sobre isso?

Ei pessoal! Obrigado pelas informações e descrições valiosas. Eu li o RFC e ainda estava um pouco confuso sobre as diferenças entre 401 e 403. No entanto, encontrei essa ótima explicação no StackOverflow. Citar:

Há um problema com 401 Unauthorized, o código de status HTTP para erros de autenticação. E é isso mesmo: é para autenticação, não para autorização.

Isso traz a questão. Zammad usa 401 para authorization erros. Isso é tecnicamente errado e, portanto, um bug. Vou reabrir o problema.

No entanto, precisamos verificar o impacto. Suponho que seja uma mudança significativa por causa de todas as implementações e consumidores de API por aí.
Meu plano atual é descontinuar o uso moderado de 401 authorization com Zammad 3.4, descontinuá-lo totalmente com 3.5 (ou 3.6) e mudar para 403.
Precisamos discutir isso mais internamente.

Mais reflexões sobre esse alguém?

Essas são ótimas notícias! Parece bom para mim.

Para mantê-lo informado: implementaremos isso na próxima versão 4.0.

Para fins de implementação interna: https://thoughtbot.com/blog/forbidden-kisses-http-fluency-in-clearance

Corrigido com o commit acima. Nós aproveitamos a chance e melhoramos algumas das mensagens de 401 erros, mas basicamente a única coisa que mudamos foram os erros de não autenticação para 403 Forbidden .

Você pode testar isso com o pacote de develop mais recente em cerca de 30 minutos a partir de agora. Esteja ciente de que este é um branch funcional e não estável. Portanto, certifique-se de ter um backup e espere o pior :) Aguardamos sua opinião!

Esta página foi útil?
0 / 5 - 0 avaliações