Discourse OpenID Connect permite que um provedor OpenID Connect seja usado como provedor de autenticação para o Discourse.
Guia de Instalação
Este plugin já vem incluído no núcleo do Discourse. Não há necessidade de instalá-lo separadamente.
Recursos
O plugin visa fornecer uma implementação mínima da especificação. Especificamente, ele suporta o “Fluxo de Código de Autorização”. Para começar, siga as instruções de instalação do plugin ou entre em contato com seu provedor de hospedagem.
Nosso plugin oauth2-basic pode ser usado para conectar-se a alguns provedores OpenID Connect (OpenID Connect é baseado em OAuth2). No entanto, este plugin exige muito menos configuração manual e pode utilizar o “ID Token” JWT caso uma API JSON não esteja disponível.
A configuração é realizada automaticamente usando um Documento de Descoberta OpenID Connect. De acordo com a especificação, ele deve estar localizado em <domínio do emissor>/.well-known/openid-configuration, mas o Discourse suporta qualquer caminho para permitir implementações não conformes (por exemplo, Azure B2C). O documento de descoberta é armazenado em cache por 10 minutos para melhorar o desempenho em sites de alto tráfego.
Se o documento de descoberta incluir um parâmetro userinfo_endpoint, o plugin o utilizará para coletar metadados do usuário. Caso contrário, o plugin extrairá metadados do id_token (um JWT) fornecido pelo endpoint de token. O plugin NÃO verifica a autenticidade da assinatura do JWT, pois isso aumentaria significativamente a complexidade. Essa decisão é respaldada pela especificação:
Se o ID Token for recebido por comunicação direta entre o Cliente e o Endpoint de Token (como ocorre neste fluxo), a validação do servidor TLS pode ser usada para validar o emissor no lugar de verificar a assinatura do token.
openid_connect_discovery_document: URL do documento de descoberta OpenID Connect. Normalmente localizado em https://seu.dominio/.well-known/openid-configuration
openid_connect_client_id: ID do cliente OpenID Connect
openid_connect_client_secret: Segredo do cliente OpenID Connect
openid connect rp initiated logout: Redirecionar o usuário para o end_session_endpoint após o logout. Deve ser suportado pelo seu provedor de identidade e incluído no documento de descoberta.
openid connect rp initiated logout redirect: (opcional) O post_logout_redirect_uri que será passado para o endpoint de logout. Se fornecido, deve estar registrado no provedor de identidade.
openid_connect_authorize_scope: Os escopos enviados para o endpoint de autorização. Deve incluir ‘openid’
openid_connect_use_pkce: Ativar Proof Key for Code Exchange (PKCE) para autenticação OpenID Connect.
openid_connect_verbose_logging: Registrar informações detalhadas de autenticação openid-connect em /logs. Mantenha isso desativado durante o uso normal.
Opções de Configuração Avançada
openid_connect_token_scope: Os escopos enviados ao solicitar o endpoint de token. A especificação oficial não exige isso.
openid_connect_error_redirects: Se o error_reason do callback contiver o primeiro parâmetro, o usuário será redirecionado para a URL no segundo parâmetro. Usado para implementações incomuns que enviam erros em resposta a entradas do usuário (por exemplo, Azure B2C)
openid_connect_allow_association_change: Permitir que os usuários desconectem e reconectem suas contas do Discourse do provedor OpenID Connect
openid_connect_groups_claim: O nome da claim na resposta OIDC[1] que contém os grupos do usuário como um array de strings. Deixe em branco para desativar a sincronização de grupos. Veja Sincronização de Grupos abaixo.
openid_connect_user_field_mappings: Mapeamentos de claims OIDC[2] que serão armazenados nos Campos de Usuário do Discourse. Os campos de usuário são identificados pelo seu ID numérico, que pode ser encontrado na URL ao editá-los pelo painel administrativo.
Sincronização de Grupos
O plugin pode sincronizar automaticamente as associações de grupos do seu provedor OpenID Connect para os grupos do Discourse. A cada login, o plugin lerá a claim configurada do token OIDC e atualizará as associações de grupos do usuário conforme necessário. Para ativar a sincronização de grupos:
Configure seu provedor de identidade para retornar um array de grupos em uma das claims. Isso deve ser um array de strings.
Defina openid_connect_groups_claim como o nome da claim no token OIDC que contém os grupos do usuário (por exemplo, cognito:groups). Uma vez definido, a sincronização das informações para o sistema de “Grupos Associados” do Discourse começará.
Encontre o Grupo do Discourse que deseja vincular. Vá em „Configurações
Olá,\nestamos usando o Plugin de Autenticação OpenID Connect com uma instalação do Discourse na AWS.
Temos os contêineres Discourse, Discourse Sidekiq e Redis implantados (baseados no Bitnami, mas por favor, não me expulsem ;)). O banco de dados está rodando na AWS RDS. Usamos o KeyCloak.
As coisas funcionam.
Mas às vezes, após uma reinicialização da Tarefa AWS do Discourse, acontece que ele pensa que tem o documento de descoberta em cache, mas não há nenhum documento lá. E ele não tenta recuperá-lo novamente do KeyCloak:
OIDC Log: Discovery document loaded from cache
OIDC Log: Discovery document is
---
(oidc) Request phase initiated.
(oidc) Authentication failure! openid_connect_discovery_error: OmniAuth::OpenIDConnect::DiscoveryError, Discovery document is missing
No aplicativo do navegador, vejo: Incapaz de buscar configuração do provedor de identidade. Por favor, tente novamente.
Tenho um requisito semelhante ao do @Tomáš_Guba: gostaria de obter um valor de uma entrada personalizada no perfil do usuário e usá-lo em um campo de usuário [personalizado].
No meu caso particular, tenho um documento de descoberta com um userinfo_endpoint
Olá, consegui fazer o plugin funcionar com meu SSO openID mas ele não vem preenchido no campo de nome de usuário do outro sistema ou e-mail entre outros campos…\n\nImagino que deva configurar algo no campo "openid connect claims", mas não sei como configurar este campo diretamente. Alguém pode me dar um exemplo? Seguem alguns prints de como está meu projeto:\nhttps://imgur.com/gallery/LWvkJUV
Existe alguma forma de evitar “perder” a rota original ao fazer login em uma postagem privada?
Se visitarmos uma página privada e clicarmos em um dos botões de login nessa página, ao sermos redirecionados de volta para o site, acabamos na página de categorias.
Você pode, por favor, dar uma olhada no problema mencionado na postagem a seguir? Eu gostaria de usar o plugin OIDC em vez do OAuth básico. Mas eu enfrento o mesmo problema - não consigo passar parâmetros para a solicitação /authorize. Eu coloco o valor no plugin no formato foo=bar.
Não consegui fazer isso funcionar no LinkedIn. Alguém mais conseguiu? Consigo fazer login no LinkedIn após ser redirecionado para lá ao clicar no botão “entrar com…” e depois “permitir” que meu aplicativo use meu e-mail do LinkedIn, então recebo “Desculpe, ocorreu um erro ao autorizar sua conta. Por favor, tente novamente.”
(oidc) Falha na autenticação! openid_connect_discovery_error: OmniAuth::OpenIDConnect::DiscoveryError, Documento de descoberta está faltando
Log OIDC: Buscar documento de descoberta gerou erro Faraday::ConnectionFailed FinalDestination: falha na consulta
Tenho a configuração do meu plugin “documento de descoberta de conexão openid” definida em Configurações do Administrador como: https://<auth_provider>/.well-known/openid-configuration e consigo acessá-lo com sucesso no contêiner Docker do aplicativo que está em execução com um comando Curl e até mesmo no console Rails.
Alguma ideia de por que estou recebendo esses erros? Não consigo integrar corretamente por causa disso. Além disso, estou atrás da intranet e usando um proxy da empresa, se isso ajudar. Como eu disse, com o proxy habilitado no ENV do contêiner, consigo acessar corretamente o URL “documento de descoberta de conexão openid”.
Nova pergunta: este plugin lida com gerenciamento de sessão? (Final: OpenID Connect Session Management 1.0).
Eu não acho, porque mesmo que o OP envie os dados session_state, não vejo em nenhum lugar no código onde eles são armazenados como cookie ou algo assim.
Então esta é uma pergunta/solicitação de recurso Seria fantástico!
Ao usar este plugin com o AWS Cognito, para fazer logout, o Cognito exige a passagem de um parâmetro client_id para a URL de logout. Pelo que pude apurar, não há como adicionar parâmetros de consulta adicionais à URL de logout - isso está correto? Caso contrário, é possível adicionar essa funcionalidade?
Escrevi uma pequena extensão para este plugin (tecnicamente na forma de um tema/componente) - para ocultar o botão “Login via OIDC” no pop-up de login, mas iniciar o fluxo de login via OIDC acessando um URL especial.
O caso de uso para este recurso é fornecer um login seguro e conveniente (automático) via oauth para os membros da nossa empresa, sem expor um link público para o provedor OAuth (Authentik no nosso caso, mas também deve funcionar com Authelia, Keycloak, Auth0, Okta,…) e sem incomodar todos os outros usuários com um botão de login via OIDC que eles nunca podem ou devem usar.
Para fazer login via OIDC, basta chamar https://<sua-url-base-do-discourse>/login#autooidc
O Keycloak suporta Backchannel logout URL (URL de logout do canal posterior):
URL que fará com que o cliente se desconecte quando uma solicitação de logout for enviada para este realm (via end_session_endpoint). Se omitido, nenhuma solicitação de logout será enviada ao cliente neste caso.
Seria ótimo se este plugin expusesse algum endpoint que aceitasse um payload do Keycloak e desconectasse imediatamente algum usuário de todas as sessões. Caso contrário, quando desabilitarmos um usuário no Keycloak, teremos que esperar o maximum session age (idade máxima da sessão) (que é bem grande por padrão).
Você também pode desconectá-los de todas as sessões usando a página de administração do usuário (por exemplo, /admin/-1/system) e clicar no botão Sair na parte superior da página.
Quando a busca do documento de descoberta falha (por exemplo, em caso de timeout), o plugin armazena o erro em cache, o que significa que a autenticação fica indisponível por 10 minutos. É possível não armazenar o erro em cache para que a busca seja tentada novamente mais cedo?