Erros ocasionais de OAuth

Estamos usando OAuth externo para autenticação de usuários. Ocasionalmente, os usuários recebem erro 500 ao acessar a plataforma: Trecho do log de erros:

Started GET "/auth/oauth2_basic/callback?code=[coderemoved]&state=[stateremoved]" for [IP] at [timestamp]
(oauth2_basic) Setup endpoint detected, running now.
(oauth2_basic) Callback phase initiated.
Faraday::TimeoutError (Timeout::Error)
lib/final_destination/resolver.rb:31:in `block in lookup'
lib/final_destination/resolver.rb:8:in `synchronize'
lib/final_destination/resolver.rb:8:in `lookup'
lib/final_destination/ssrf_detector.rb:127:in `lookup_ips'
lib/final_destination/ssrf_detector.rb:95:in `lookup_and_filter_ips'
lib/final_destination/http.rb:13:in `connect'
lib/middleware/omniauth_bypass_middleware.rb:43:in `call'
lib/middleware/content_security_policy.rb:12:in `call'
lib/middleware/anonymous_cache.rb:387:in `call'
lib/middleware/gtm_script_nonce_injector.rb:10:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
lib/middleware/enforce_hostname.rb:24:in `call'
lib/middleware/request_tracker.rb:233:in `call'

Se o usuário simplesmente recarregar a página, tudo funciona, com as seguintes informações no log:

Started GET "/auth/oauth2_basic/callback?code=[coderemoved]&state=[stateremoved]" for [IP] at [timestamp]
(oauth2_basic) Setup endpoint detected, running now.
(oauth2_basic) Callback phase initiated.
Processing by Users::OmniauthCallbacksController#complete as HTML
  Parameters: {"code"=>"[coderemoved]", "state"=>"[stateremoved]", "provider"=>"oauth2_basic"}
Deprecation notice: `SiteSetting.anonymous_posting_min_trust_level` has been deprecated. Please use `SiteSetting.anonymous_posting_allowed_groups` instead. (removal in Discourse 3.3) 
At /var/www/discourse/lib/site_setting_extension.rb:160:in `public_send`
start
Redirected to https://[pageremoved]
Completed 302 Found in 83ms (ActiveRecord: 0.0ms | Allocations: 11138)

Infelizmente, não há passos para reproduzir o problema. Ele tende a ocorrer quando usuários que ficaram ausentes por um período mais longo retornam, mas não posso confirmar isso com certeza. É possível que tenha havido uma atualização da plataforma desde a última visita deles.
Alguma sugestão ou informação adicional que eu possa fornecer?

Reabrindo este tópico. Estou tendo exatamente os mesmos problemas.

Erro de tempo limite sugere um problema de rede. Pode ser apenas uma falha na rede.

Eu pensei nisso, mas o erro surge rápido demais para ser um comportamento normal. Estou imaginando se pode haver um timeout excessivamente zeloso de consulta DNS em algum lugar:

  1. O erro está em “resolver.rb”
  2. É corrigido temporariamente com uma atualização - quando a consulta DNS seria armazenada em cache
  3. Por algum motivo completamente inexplicável, não consigo fazer com que ele leia o documento de descoberta OIDC de nenhum URL que envolva nosso DNS auto-hospedado. Isso apesar do fato de que sou perfeitamente capaz de usar curl para obter o arquivo manualmente de dentro da instância do docker. Eliminei muitas variáveis diferentes e o DNS parece ser o único fator comum.

Importante, o servidor Discourse consegue se comunicar com o servidor OIDC, mesmo quando falha assim. Pelos logs de acesso, há uma solicitação:

21/Jan/2024:23:10:21 +0000] "POST /application/o/token/ HTTP/1.1" 200 7998 "-" "Faraday v2.9.0"

quando falha, e duas solicitações:

[21/Jan/2024:23:21:03 +0000] "POST /application/o/token/ HTTP/1.1" 200 7998 "-" "Faraday v2.9.0"
[21/Jan/2024:23:21:05 +0000] "GET /application/o/userinfo/ HTTP/1.1" 200 5254 "-" "Faraday v2.9.0"

quando tem sucesso. Independentemente disso, nunca leva mais de 5 segundos. Ainda preciso tentar configurar um proxy para o servidor OIDC que use o DNS da Cloudflare, mas esse será meu próximo passo.

O senso comum é que a culpa é sempre do DNS.

Bem, é definitivamente DNS. Em vez de configurar um proxy, apenas adicionei meu servidor OIDC ao arquivo hosts no contêiner docker e parece funcionar agora. Esta é uma solução frágil e subótima, no entanto; acho que os desenvolvedores precisam corrigir o tempo limite para que seja algo razoável. Este caso me lembra a história do e-mail de 500 milhas.

Você pode adicionar coisas ao seu app.yml para atualizar /etc/hosts em uma reconstrução. Você pode olhar outros templates para exemplos.

Pode ser, mas não muitas pessoas estão tendo problemas. Seu servidor DNS auto-hospedado pode ficar sobrecarregado às vezes?

Não sei onde mudar o timeout. Nunca me lembro de ter feito isso.

No meu caso, o IdP e a VM do Discourse estão lado a lado e, embora ninguém possa excluir completamente possíveis problemas de rede, nenhum outro serviço os está experimentando.