OpenID Connect Authentication Plugin


(David Taylor) #1


discourse-openid-connect allows an OpenID Connect provider to be used as an authentication provider for Discourse. The plugin aims to provide a minimal implementation of the specification. Specifically, it supports the “Authorization Code Flow”. To get started, follow the plugin installation instructions, or contact your hosting provider.

Our oauth2-basic plugin can be used for connecting to some openid-connect providers (OpenID Connect is based on OAuth2). However, this plugin should require far less manual configuration, and can make use of the JWT “ID Token” if a JSON API is not available.

Configuration is automatically performed using an OpenID Connect Discovery Document. According to the specification, this should be located at <issuer domain>/.well-known/openid-configuration, but Discourse supports any path to allow for non-compliant implementations (e.g. Azure B2C). The discovery document is cached for 10 minutes, to improve performance on high-traffic sites.

If the discovery document includes a userinfo_endpoint parameter, then the plugin will use that to collect user metadata. If not, the plugin will extract metadata from the id_token (A JWT) supplied by the token endpoint. The plugin DOES NOT verify the authenticity of the JWT signature, as this would significantly increase complexity. This decision is supported by the specification:

If the ID Token is received via direct communication between the Client and the Token Endpoint (which it is in this flow), the TLS server validation MAY be used to validate the issuer in place of checking the token signature.

Basic Configuration Options

  • openid_connect_enabled: Enable OpenID Connect authentication

  • openid_connect_discovery_document: OpenID Connect discovery document URL. Normally located at https://your.domain/.well-known/openid-configuration

  • openid_connect_client_id: OpenID Connect client ID

  • openid_connect_client_secret: OpenID Connect client secret

  • openid_connect_authorize_scope: The scopes sent to the authorize endpoint. This must include ‘openid’

Advanced Configuration Options

  • openid_connect_token_scope: The scopes sent when requesting the token endpoint. The official specification does not require this.

  • openid_connect_error_redirects: If the callback error_reason contains the first parameter, the user will be redirected to the URL in the second parameter. Used for unusual implementations that send errors in response to user input (e.g. Azure B2C)

  • openid_connect_allow_association_change: Allow users to disconnect and reconnect their Discourse accounts from the OpenID Connect provider

Example setup

Here we will set up the openid-connect plugin to connect to Google’s OpenID Connect provider. This replicates functionality that already exists in the core of Discourse, but it serves as an accessible example.

  1. Head to OpenID Connect  |  Google Identity Platform  |  Google Developers and follow the instructions to obtain OAuth Credentials.

  2. On the same page, follow the instructions to add a redirect URI. This should be https://<your_forum>/auth/oidc/callback (without a trailing slash)

  3. Go to your Discourse site settings and search for “openid_connect”

    • openid connect enabled:

    • openid connect discovery document:

    • openid connect client id: <client-id>

    • openid connect client secret: <client-secret>

    • openid connect authorize scope: openid email (with a space in between)

  4. You’re done. The “Login with OpenID Connect” button will now log in using Google :tada:. These same steps can be applied to other providers, with very minimal changes.

Support for OpenID Connect (OIDC)
Custom provider using OpenID Connect via IdentityServer3
Installing own gem in plugin
(Klāvs Priedītis) #2

The plugin works great for already registered users.
I’d like to get users signed up using the OpenIDConnect provider exclusively.

Am I correct to observe that this is an issue outside of the scope of this plugin?
Seems to me that Discourse can be set up to use 1 to N login methods, but supports only one sign-up method (either local or sso) even in cases where I disable every other login method except OpenID provider.

What would be the recommended way to allow sign-ups of only those users which are registered to my OpenID provider?

From what I found, I’d need to have an external sso service which would mediate the communication between Discource and my OpenID provider.

Please correct me if I’m wrong in my observations.

(David Taylor) #3

If you “log in” using OpenID connect (or any other authentication provider), and there is no existing account, you will be able to register via that method.

If you disable all other authentication methods, sign up will only be possible via OpenID Connect.

Does that solve what you’re trying to achieve? If not, maybe you can give an example of what behaviour you are expecting?

(Klāvs Priedītis) #4

I think we are on the same page in regards to my expectations.

I just found that the issue I have is
ActionDispatch::Cookies::CookieOverflow on /auth/oidc/callback.

It just happens to affect non-registered users.

(David Taylor) #5

I think I know what’s going on here - I’ll have a look in the next couple of days and let you know when it’s fixed.

(David Taylor) #6

The CookieOverflow issue should now be fixed - we now persist the data in the database rather than a cookie:

Please try updating to the latest version of Discourse, and try again. (this is a change to discourse core, not the plugin). Let me know if you’re still running into issues.

OAuth2 and Microsoft ADFS
(Klāvs Priedītis) #7

Thanks! It works now!

Now we can get back to the original problem:

Is there a way (without writing my own plugin or implementing Discourse sso service) to prevent users from signing up, except when they already have an account with my OpenID provider?

(David Taylor) #8

Yes, just disable the enable local logins setting in your site settings. That will make the login and signup buttons connect directly to your openid-connect provider.