Discourse OpenID Connect (OIDC)

:discourse2: Resumen Discourse OpenID Connect permite utilizar un proveedor de OpenID Connect como proveedor de autenticación para Discourse.
:open_book: Guía de instalación Este plugin está incluido en el núcleo de Discourse. No es necesario instalar el plugin por separado.

Funcionalidades

El plugin busca proporcionar una implementación mínima de la especificación. Específicamente, admite el “Flujo de código de autorización”. Para empezar, sigue las instrucciones de instalación del plugin o contacta a tu proveedor de alojamiento.

Nuestro plugin oauth2-basic puede utilizarse para conectarse a algunos proveedores de OpenID Connect (OpenID Connect se basa en OAuth2). Sin embargo, este plugin debería requerir mucha menos configuración manual y puede hacer uso del “token de identificación” JWT si no está disponible una API JSON.

La configuración se realiza automáticamente utilizando un documento de descubrimiento de OpenID Connect. Según la especificación, este debería ubicarse en <dominio_emisor>/.well-known/openid-configuration, pero Discourse admite cualquier ruta para permitir implementaciones no conformes (por ejemplo, Azure B2C). El documento de descubrimiento se almacena en caché durante 10 minutos para mejorar el rendimiento en sitios con alto tráfico.

Si el documento de descubrimiento incluye un parámetro userinfo_endpoint, el plugin lo utilizará para recopilar metadatos del usuario. De lo contrario, el plugin extraerá los metadatos del id_token (un JWT) proporcionado por el punto final de token. El plugin NO verifica la autenticidad de la firma JWT, ya que esto aumentaría significativamente la complejidad. Esta decisión está respaldada por la especificación:

Si el token de identificación se recibe mediante comunicación directa entre el cliente y el punto final de token (que es el caso en este flujo), la validación del servidor TLS puede utilizarse para validar el emisor en lugar de verificar la firma del token.

Para los proveedores de identidad que admiten autorización sin secreto utilizando el “Flujo de código de autorización con clave de prueba para intercambio de código”, PKCE debe estar habilitado y la configuración client_secret puede omitirse.

Configuración

Opciones de configuración básica

  • openid_connect_enabled: Habilitar la autenticación OpenID Connect

  • openid_connect_discovery_document: URL del documento de descubrimiento de OpenID Connect. Normalmente ubicado en https://tu.dominio/.well-known/openid-configuration

  • openid_connect_client_id: ID de cliente de OpenID Connect

  • openid_connect_client_secret: Secreto de cliente de OpenID Connect

  • openid connect rp initiated logout: Redirigir al usuario al end_session_endpoint después de cerrar sesión. Debe ser compatible con tu proveedor de identidad e incluirse en el documento de descubrimiento.

  • openid connect rp initiated logout redirect: (opcional) El post_logout_redirect_uri que se pasará al punto final de cierre de sesión. Si se proporciona, debe estar registrado con el proveedor de identidad.

  • openid_connect_authorize_scope: Los ámbitos enviados al punto final de autorización. Esto debe incluir ‘openid’

  • openid_connect_use_pkce: Habilitar la Clave de Prueba para Intercambio de Código (PKCE) para la autenticación OpenID Connect.

  • openid_connect_verbose_logging: Registrar información detallada de autenticación openid-connect en /logs. Mantén esto deshabilitado durante el uso normal.

Opciones de configuración avanzada

  • openid_connect_token_scope: Los ámbitos enviados al solicitar el punto final de token. La especificación oficial no lo requiere.

  • openid_connect_error_redirects: Si el error_reason de la devolución de llamada contiene el primer parámetro, el usuario será redirigido a la URL en el segundo parámetro. Se utiliza para implementaciones inusuales que envían errores en respuesta a la entrada del usuario (por ejemplo, Azure B2C).

  • openid_connect_allow_association_change: Permitir a los usuarios desconectar y reconectar sus cuentas de Discourse del proveedor de OpenID Connect.

  • openid_connect_groups_claim: El nombre de la reclamación en la respuesta OIDC[1] que contiene los grupos del usuario como un array de cadenas. Déjalo en blanco para deshabilitar la sincronización de grupos. Consulta Sincronización de grupos a continuación.

  • openid_connect_user_field_mappings: Mapeos de reclamaciones OIDC[2] que se almacenarán en los campos de usuario de Discourse. Los campos de usuario se identifican por su ID numérico, que se puede encontrar en la URL al editarlos desde el panel de administración.

Sincronización de grupos

El plugin puede sincronizar automáticamente las membresías de grupos desde tu proveedor de OpenID Connect hacia los grupos de Discourse. En cada inicio de sesión, el plugin leerá la reclamación configurada del token OIDC y actualizará las membresías de grupo del usuario en consecuencia. Para habilitar la sincronización de grupos:

  1. Configura tu proveedor de identidad para que devuelva un array de grupos en una de las reclamaciones. Debe ser un array de cadenas.

  2. Establece openid_connect_groups_claim con el nombre de la reclamación en el token OIDC que contiene los grupos del usuario (por ejemplo, cognito:groups). Una vez establecido, comenzará a sincronizar la información con el sistema de “Grupos asociados” de Discourse.

  3. Busca el grupo de Discourse que deseas vincular. Ve a “Configuración” → “Membresía” → “Automático” y luego elige los Grupos asociados para vincular. Esta lista desplegable se llena con información del proveedor de identidad, por lo que al menos un miembro del grupo debe haber iniciado sesión para que aparezca una opción.

Configuración de ejemplo

Aquí configuraremos el plugin openid-connect para conectarse al proveedor de OpenID Connect de Google. Esto replica una funcionalidad que ya existe en el núcleo de Discourse, pero sirve como un ejemplo accesible.

  1. Ve a OpenID Connect  |  Sign in with Google  |  Google for Developers y sigue las instrucciones para obtener credenciales de OAuth.

  2. En la misma página, sigue las instrucciones para agregar una URI de redirección. Debe ser https://<tu_foro>/auth/oidc/callback (sin barra final)

  3. Ve a la configuración de tu sitio de Discourse y busca “openid_connect”

    • openid connect enabled: [x]

    • openid connect discovery document: https://accounts.google.com/.well-known/openid-configuration

    • openid connect client id: <client-id>

    • openid connect client secret: <client-secret>

    • openid connect authorize scope: openid email (con un espacio entre ellos)

  4. ¡Listo! El botón “Iniciar sesión con OpenID Connect” ahora iniciará sesión usando Google :tada:. Estos mismos pasos pueden aplicarse a otros proveedores con cambios mínimos.

Depuración

Además de la configuración verbose_logging descrita anteriormente, puedes acceder a datos sobre las asociaciones OIDC usando el plugin data-explorer:

SELECT user_id, provider_name, provider_uid
FROM user_associated_accounts
WHERE provider_name = 'oidc'

O en la consola de rails:

User.find_by_username("david").user_associated_accounts.where(provider_name: 'oidc')

Notas específicas del proveedor

Siéntete libre de actualizar esto si encuentras cualquier peculiaridad específica del proveedor relacionada con esta integración:

Entra ID (anteriormente Azure AD)

Agrega el ámbito email y asegúrate de estar utilizando el documento de configuración del punto final de versión 2. Por ejemplo

https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration
Azure B2C

Los detalles de la URL del documento de descubrimiento se pueden encontrar aquí: Web sign in with OpenID Connect - Azure AD B2C | Microsoft Learn

Para que los correos electrónicos funcionen:

Yahoo
  1. Ve a https://developer.yahoo.com/apps y crea una nueva aplicación

  2. Ingresa el nombre de la aplicación y establece el dominio de devolución de llamada en el dominio de tu foro (por ejemplo, meta.discourse.org)

  3. En Permisos de API, elige Perfiles: Lectura/Escritura pública y privada. Esta es la única forma que conozco para obtener la dirección de correo electrónico del usuario

  4. Guarda la aplicación

  5. En la configuración de OIDC de Discourse, establece el documento de descubrimiento en

    https://login.yahoo.com/.well-known/openid-configuration
    
  6. Ingresa el ID de cliente y el secreto de Yahoo

  7. Habilita el plugin OIDC

AWS Cognito
  1. Ve a Cognito y selecciona o crea un nuevo grupo de usuarios.
  2. Define una aplicación en Clientes de aplicaciones.
  3. Deja todo por defecto, pero cambia la configuración de flujos de autenticación para seleccionar solo ALLOW_REFRESH_TOKEN_AUTH.
  4. Ve a la configuración del cliente de aplicaciones y selecciona la nueva aplicación.
  5. Cambia la URL de devolución de llamada a https://tusitio.ejemplo.com/auth/oidc/callback.
  6. Marca solo el flujo de concesión de código de autorización entre “Flujos OAuth permitidos”.
  7. Marca todos los ámbitos necesarios (yo tengo todos marcados).
Okta
  1. Configura Discourse con el ID y el secreto de cliente de tu aplicación Okta

  2. Establece la URL del documento de descubrimiento en

    https://{tu-app}.okta.com/.well-known/openid-configuration
    
  3. En Discourse, establece openid connect authorize scope en openid email

:discourse2: ¿Alojado por nosotros? Este plugin está disponible en nuestros planes Business y Enterprise. OAuth 2.0 & OpenID Connect Support | Discourse - Civilized Discussion


  1. token o carga útil de userinfo ↩︎

  2. del token o carga útil de userinfo ↩︎

52 Me gusta
Native SSO with Azure AD
How to setup okta authentication with discourse
Discourse Login using external API
OpenIdAuthenticator plugin fails
Sign in to Discourse using ORCID
Discourse, Keycloak, SAML vs OAuth
OpenID Connect support in selfhosted Discourse instance
How can you connect firebase to discourse?
Keycloak SSO and logout issue
Tutorial for OpenID Connect / Azure AD
OpenID connect plugin
Azure OpenID Connect Authentication Plugin
Installing own gem in plugin
SSO Login page not showing up
Enabling Okta for employees only through OpenID Connect Authentication Plugin
Is "partial" SSO possible?
Auto-sign-in with the OpenId Connect Plugin and AWS Cognito
Official support for Microsoft Azure AD?
CodeBerg support
Availability of OpenID Connect in hosted plans
Can we use the default atlassian id to login to discourse
OpenIdAuthenticator plugin fails
Intergrate Discourse with keycloak
IndieAuth login
Intergrate Discourse with keycloak
Map oidc fields to custom user fields
CSRF problem in development with 'Discourse OpenID Connect' plug-in
Azure B2C SSO to Discourse?
User (patron) getting authorization error message
Memberstack + Webflow + Discourse OpenID Connect
How can add 2 or more discovery documents?
Memberstack + Webflow + Discourse OpenID Connect
Azure AD Authentication and Creation of User Account
Possible to create a Sign in with Ghost plugin for Discourse?
Custom Login Flow: AWS Cognito SSO (via Passwordless Signin) - Is this possible?
Account already in discourse
AAD integration with Discourse
Having trouble setting up AWS Cognito passwordless login
Discourse ID fails to activate on my instance
Restrict Office 365 Login to certain Group
OpenID Connect Plugin not creating new users with AWS Cognito
OIDC users not associating with existing Discourse users
Bundling more popular plugins with Discourse core
OpenID Connect Plugin Refactor (OIDC Implicit Flow)
Availability of OpenID Connect in hosted plans
How to configure the OIDC to set the Username as the email account name or a username like value returned from my auth providers?
Managing group membership via authentication
Failed to bootstrap due to out of memory killer
OAuth connection of discourse
Auto-provisioning user accounts when SSO is enabled
Anyone have a working AWS Cognito configuration w/ ouath2, openid or sso?
SAML Plugin on Self Hosted Discourse
Can I include website analytics in trust data?
Using OpenID Connect with User Flows in Azure B2C
ADFS Authentication
How to set-up Discourse with Atricore Josso CE
Error of Discourse OpenID Connect
How can add 2 or more discovery documents?
./launcher rebuild app fails hard 'bundle exec rake db:migrate' possible issue with github/master repo removal of auth/oath2_authenticator
Removing Yahoo login from Core, and deprecating OpenID 2.0
SSO with TownNews CMS
OpenID Connect Plugin Refactor (OIDC Implicit Flow)
OpenID with line.biz - email in JWT , missing in userinfo

Hola,\n\nestamos utilizando el plugin de autenticación OpenID Connect con una instalación de Discourse en AWS.\nHemos implementado los contenedores Discourse, Discourse Sidekiq y Redis (basado en Bitnami, pero por favor no me echen ;). La base de datos se ejecuta en AWS RDS. Usamos KeyCloak.\n\nLas cosas funcionan.\n\nPero a veces, después de reiniciar la Tarea de AWS de Discourse, sucede que cree que tiene el documento de descubrimiento en la caché, pero luego no hay ningún documento allí. Y no intenta recuperarlo de KeyCloak:\n\n\n\nOIDC Log: Discovery document loaded from cache\nOIDC Log: Discovery document is\n---\n(oidc) Request phase initiated.\n(oidc) Authentication failure! openid_connect_discovery_error: OmniAuth::OpenIDConnect::DiscoveryError, Discovery document is missing\n\nEn la aplicación del navegador veo: No se puede obtener la configuración del proveedor de identidad. Por favor, inténtelo de nuevo.\n\n¿Qué puedes aconsejar?

2 Me gusta

Hola,

¿Hay alguna forma de establecer la fuente del avatar del usuario de Discourse en un campo especificado en el servicio openID?

Editar: estamos usando keycloak

1 me gusta

Hola,

Tengo un requisito similar al de @Tomáš_Guba: me gustaría obtener un valor de una entrada personalizada en el perfil del usuario y usarlo en un campo de usuario [personalizado].

En mi caso particular, tengo un documento de descubrimiento con un userinfo_endpoint.

¿Hay algo así en la hoja de ruta del plugin?

Gracias

1 me gusta

Hola, logré hacer funcionar el plugin con mi openID SSO pero no me viene rellenado el campo username del otro sistema ni el email entre otros campos…

Me imagino que debería configurar algo en el campo “openid connect claims”, pero no se como configurar este campo directamente. ¿Alguien me puede poner un ejemplo? Aquí os dejo unas capturas de como tengo mi proyecto:
https://imgur.com/gallery/LWvkJUV

1 me gusta

¿Hay alguna forma de evitar “perder” la ruta original al iniciar sesión en una publicación privada?

Si visitamos una página privada y hacemos clic en cualquiera de los botones de inicio de sesión en esa página, al ser redirigidos de nuevo al sitio, terminamos en la página de categorías.

Hola @david,

¿Puedes echar un vistazo al problema mencionado en la siguiente publicación? Me gustaría usar el plugin OIDC sobre OAuth básico. Pero me enfrento al mismo problema: no puedo pasar parámetros a la solicitud /authorize. Pongo el valor en el plugin en formato foo=bar.

No he podido hacer que esto funcione en LinkedIn. ¿Alguien más lo ha intentado? Llego hasta el inicio de sesión en LinkedIn después de ser redirigido allí al hacer clic en el botón “iniciar sesión con…” y luego “permitir” que mi aplicación use mi correo electrónico de LinkedIn, luego me aparece “Lo sentimos, hubo un error al autorizar su cuenta. Por favor, inténtelo de nuevo”.

https:/discourse.mysite.com/auth/failure?message=invalid_credentials&origin=https%3A%2F%2Fdiscourse.mysite.com%2F&strategy=oidc

Todavía tengo problemas con esto. Estoy recibiendo el siguiente error:

(oidc) Fallo de autenticación! invalid_credentials: OAuth2::Error, invalid_request: Falta un parámetro requerido "client_secret" {"error":"invalid_request","error_description":"A required parameter

Es un error de omniauth y parece estar relacionado [potencialmente] con esto: No longer works with oauth2 gem v2.0+ · Issue #68 · decioferreira/omniauth-linkedin-oauth2 · GitHub

¡Se agradece la ayuda!

Recibo los siguientes errores:


(oidc) ¡Fallo de autenticación! openid_connect_discovery_error: OmniAuth::OpenIDConnect::DiscoveryError, el documento de descubrimiento falta

Registro OIDC: la obtención del documento de descubrimiento generó un error Faraday::ConnectionFailed FinalDestination: la búsqueda falló

Tengo la configuración de mi plugin “documento de descubrimiento de openid connect” establecida en la Configuración de administrador como: https://<auth_provider>/.well-known/openid-configuration y puedo acceder a él con éxito en el contenedor Docker de la aplicación que se está ejecutando con un comando Curl e incluso en la consola de Rails.

¿Alguna idea de por qué recibo estos errores? No puedo integrarme correctamente debido a esto. Además, estoy detrás de la intranet y uso un proxy de la empresa si eso ayuda. Como dije, con el proxy habilitado en el ENV del contenedor, puedo acceder correctamente a la URL del “documento de descubrimiento de openid connect”.

1 me gusta

2 publicaciones se dividieron en un nuevo tema: Permitir múltiples fuentes OIDC

Se dividió una publicación en un nuevo tema: Anular avatares con OIDC

Hola!

Nueva pregunta: ¿este plugin maneja la gestión de sesiones? (Final: OpenID Connect Session Management 1.0).
No creo que sea así porque, incluso si el OP envía los datos de session_state, no veo en ninguna parte del código dónde se almacena como una cookie o algo similar.

Así que esto es una pregunta/solicitud de función :slight_smile: ¡Sería fantástico!

2 Me gusta

Al usar este plugin con AWS Cognito, para cerrar sesión, Cognito requiere pasar un parámetro client_id a la URL de cierre de sesión. Por lo que he podido averiguar, no hay forma de añadir parámetros de consulta adicionales a la URL de cierre de sesión, ¿es correcto? Si no es así, ¿es posible añadir esta capacidad?

Hola a todos :wave:t3:

He escrito una pequeña extensión para este plugin (técnicamente en forma de tema/componente) para ocultar el botón “Iniciar sesión a través de OIDC” en la ventana emergente de inicio de sesión, pero iniciar el flujo de inicio de sesión a través de OIDC accediendo a una URL especial.

discourse-autooidc.zip (1,0 KB)

El caso de uso para esta función es proporcionar un inicio de sesión seguro y conveniente (automático) a través de OAuth para los miembros de nuestra empresa, sin exponer un enlace público al proveedor de OAuth (Authentik en nuestro caso, pero también debería funcionar con Authelia, Keycloak, Auth0, Okta,…) y sin molestar a todos los demás usuarios con un botón de inicio de sesión a través de OIDC que nunca podrán o deberían usar.

Para iniciar sesión a través de OIDC, simplemente llame a https://<tu-url-base-de-discourse>/login#autooidc

3 Me gusta

Puede que te interese GitHub - discourse/discourse-hide-auth-method: A theme component which allows hiding a specific login method from the UI, without fully disabling it, que hace algo similar

3 Me gusta

Keycloak admite la URL de cierre de sesión del canal posterior:

URL que provocará que el cliente cierre su propia sesión cuando se envíe una solicitud de cierre de sesión a este realm (a través de end_session_endpoint). Si se omite, no se enviará ninguna solicitud de cierre de sesión al cliente en este caso.

Sería genial si este plugin expusiera algún endpoint que acepte la carga útil de Keycloak y cierre la sesión de algún usuario de todas las sesiones inmediatamente. De lo contrario, cuando deshabilitamos al usuario en Keycloak, debemos esperar la edad máxima de la sesión (que es bastante grande por defecto).

También podrías cerrarles la sesión de todas las sesiones usando la página de administración del usuario (por ejemplo, /admin/-1/system) y hacer clic en el botón Log Out en la parte superior de la página.

Hola,

Cuando la obtención del documento de descubrimiento falla (por ejemplo, cuando hay un tiempo de espera agotado), el plugin almacena en caché el error, lo que significa que la autenticación no está disponible durante 10 minutos. ¿Es posible no almacenar en caché el error para que la obtención se reintente antes?

Saludos

Disculpa la interrupción, pero hay una PR abierta para esto que debería ser trivial de fusionar para añadir soporte PKCE.

@nbianca Vi que eras el último en confirmar en el repositorio, ¿podrías echarle un vistazo, quizás? :folded_hands:

1 me gusta