OpenID Connect プラグインのリファクタリング

Hey everyone,

I’m looking to improve our security posture, and part of that means that we need to avoid using secret credentials whenever we can.
Unfortunately the OIDC plugin required a client secret credential to hit the /userinfo endpoint, and I couldn’t set up my forum with it enabled.

Fortunately, the OIDC specification is actually defined in a way that doesn’t require the use of any secret tokens.
If we stick to the id_token flow, the IdP will send us all of the information we need to authenticate a user without having to reach back out to the IdP.

This is secure because the redirect is configured in the IdP, and we don’t have to worry about the bearer token being forwarded to the wrong destination.

I went ahead and created a patch for the OIDC plugin to support the id_token flow and submitted a pull request here:

The PR isn’t quite complete since it still needs unit tests, but it’s pretty much there and I’ve confirmed that this works properly with Azure AD (Entra ID).

For ref, here is the documentation for the OIDC plugin:

「いいね!」 1

I think what you’re describing here is the OpenID Connect “Implicit Flow”, which works without any server->server communication, and therefore doesn’t need a shared secret. Instead, all information is transmitted via the HTTP redirects, and the ID token is cryptographically verified using the public keys from the Discovery Document.

That’s fine, and I think it’s a valid feature request. But it’s a very different system to our current plugin, which uses the authorization code flow. This flow uses server->server communication with a shared secret, and therefore no cryptographic verification of the id_token is needed. This is simpler in some ways, but more complex in others.

Importantly: we can’t just change the default implementation in the plugin. Sites which are using the authorization-code flow need to keep using that. IIRC many identity providers don’t even support the Implicit Flow.

So I think there are two paths forward here:

  1. We add support for the “implicit flow” in the OIDC plugin, but make it an opt-in thing. I think it’s unlikely we’ll accept a PR which introduce the openid-connect gem as a dependency of Discourse core, so therefore it would need to be implemented within our current strategy.

    The discourse-lti (learning tools integration) plugin may be a useful source of inspiration, because the LTI protocol is based on the OIDC implicit flow. The id_token decode logic is here

or alternatively

  1. You build the implicit flow as a totally new plugin. In this case you’d be free to do whatever you like in terms of implementation (but you’d also have to maintain it yourself)

Also worth noting that the OIDC “Implicit Flow” does increase the surface area for CSRF attacks and token exposure:

I think it can still make sense for some situations. But it seems like the Authorization Code flow (Discourse’s default) with PKCE (optional in Discourse) is the most-recommended way to use OIDC.

So it may be worth reconsidering this statement:

Is switching to the OIDC implicit flow, and therefore transmitting all your user information via the client, really an improved security posture? :thinking: