# CSRF problem in development with 'Discourse OpenID Connect' plug-in

**URL:** https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786
**Category:** Development
**Created:** [October 19, 2023, 12:05pm UTC](https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786 "2023-10-19T12:05:40Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![wayway\_way](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wayway_way/32/327018_2.png) [@wayway\_way](https://meta.discourse.org/u/wayway_way)
#### Post date: [October 19, 2023, 12:05pm UTC](https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786/1 "2023-10-19T12:05:40Z")

</div>

I spent five or six weeks setting up Discourse’s SSO, and encountered some problems during this period. Now there is a problem that is blocking me. I will record this problem in as much detail as possible.

# Development environment

- ubuntu22 on vmware
- [discourse 3.2.0.beta2-dev](https://github.com/discourse/discourse/commits/cb8190d32f549b9f7f2d7642b80ac22fb151bf0b)
  - server runs on 127.0.0.1:3000
  - ember-cli runs on 127.0.0.1:4200
  - [Install Discourse on Ubuntu or Debian for Development](https://meta.discourse.org/t/install-discourse-on-ubuntu-or-debian-for-development/14727)
  - disabled plugins
    - presence
    - chat
    - narrative bot

  - Use plug-in [Discourse OpenID Connect](https://meta.discourse.org/t/discourse-openid-connect/103632) to connect kecloak based on OIDC, keycloak as the identity provider of discourse
    - OIDC connection configuration on [Discourse OpenID Connect](https://meta.discourse.org/t/discourse-openid-connect/103632)
      - openid connect discovery document: `http://127.0.0.1:8080/realms/mediawiki-realm/.well-known/openid-configuration`
      - openid connect client id: `mydiscourse`
      - openid connect client secret: `O9A8zQuOn1bfpsWD89U8ULwYf6ooDu73`

- sso provider keycloak 22.0.4
  - runs on 127.0.0.1:8080
  - OIDC connection configuration on keycloak
    - Valid redirect URIs: `http://127.0.0.1:3000/auth/oidc/callback`
    - Client secret: `O9A8zQuOn1bfpsWD89U8ULwYf6ooDu73`

- chrome version 118.0.5993.70

# Reproduction process

## Log in with OIDC

 ![image](https://global.discourse-cdn.com/meta/original/4X/2/1/c/21c32e7b66b7a0faa3263690657e35b90eef1dbb.png)

## Discourse redirects to keycloak, enter user information in keycloak

 ![image](https://global.discourse-cdn.com/meta/original/4X/2/b/6/2b66b31a4a32447e23b60d1e76801a32fd108d8e.jpeg)

## CSRF

 ![image](https://global.discourse-cdn.com/meta/original/4X/c/5/3/c537a5fe731a18bedebd6e53dc611e828a713d08.jpeg)

# Logs

 ![image](https://global.discourse-cdn.com/meta/original/4X/5/1/0/51035f86978b3f345a48f9e4b0486512c61e8de9.png)  
//  
 ![image](https://global.discourse-cdn.com/meta/original/4X/c/3/a/c3a331c8d4e32dbf692a71fd10ee37b8d61f34be.jpeg)  
//  
 ![image](https://global.discourse-cdn.com/meta/original/4X/9/e/7/9e79554a6f844d435cc1d62b6017964eda333653.jpeg)  
//  
 ![image](https://global.discourse-cdn.com/meta/original/4X/9/a/c/9acfb5476b7ef25cac9fd3072323669fa31ad0a3.png)  
// Application Trace

```plaintext
lib/middleware/omniauth_bypass_middleware.rb:53:in `call'
lib/content_security_policy/middleware.rb:12: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/missing_avatars.rb:22:in `call'
lib/middleware/turbo_dev.rb:31:in `call'

```

// Framework Trace

```plaintext
omniauth (1.9.2) lib/omniauth/failure_endpoint.rb:25:in `raise_out!'
omniauth (1.9.2) lib/omniauth/failure_endpoint.rb:20:in `call'
omniauth (1.9.2) lib/omniauth/failure_endpoint.rb:12:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:491:in `fail!'
/home/hardway/Downloads/omniauth-oauth2/lib/omniauth/strategies/oauth2.rb:88:in `callback_phase'
plugins/discourse-openid-connect/lib/omniauth_open_id_connect.rb:142:in `callback_phase'
omniauth (1.9.2) lib/omniauth/strategy.rb:238:in `callback_call'
omniauth (1.9.2) lib/omniauth/strategy.rb:189:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/builder.rb:45:in `call'
rack (2.2.8) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.8) lib/rack/conditional_get.rb:27:in `call'
rack (2.2.8) lib/rack/head.rb:12:in `call'
actionpack (7.0.7) lib/action_dispatch/http/permissions_policy.rb:38:in `call'
rack (2.2.8) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.8) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/cookies.rb:704:in `call'
activerecord (7.0.7) lib/active_record/migration.rb:603:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (7.0.7) lib/active_support/callbacks.rb:99:in `run_callbacks'
actionpack (7.0.7) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/show_exceptions.rb:29:in `call'
logster (2.13.0) lib/logster/middleware/reporter.rb:40:in `call'
railties (7.0.7) lib/rails/rack/logger.rb:40:in `call_app'
railties (7.0.7) lib/rails/rack/logger.rb:27:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/request_id.rb:26:in `call'
rack (2.2.8) lib/rack/method_override.rb:24:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/static.rb:23:in `call'
rack (2.2.8) lib/rack/sendfile.rb:110:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/host_authorization.rb:137:in `call'
rack-mini-profiler (3.1.1) lib/mini_profiler.rb:413:in `call'
message_bus (4.3.8) lib/message_bus/rack/middleware.rb:60:in `call'
railties (7.0.7) lib/rails/engine.rb:530:in `call'
railties (7.0.7) lib/rails/railtie.rb:226:in `public_send'
railties (7.0.7) lib/rails/railtie.rb:226:in `method_missing'
rack (2.2.8) lib/rack/urlmap.rb:74:in `block in call'
rack (2.2.8) lib/rack/urlmap.rb:58:in `each'
rack (2.2.8) lib/rack/urlmap.rb:58:in `call'
unicorn (6.1.0) lib/unicorn/http_server.rb:634:in `process_client'
unicorn (6.1.0) lib/unicorn/http_server.rb:739:in `worker_loop'
unicorn (6.1.0) lib/unicorn/http_server.rb:547:in `spawn_missing_workers'
unicorn (6.1.0) lib/unicorn/http_server.rb:143:in `start'
unicorn (6.1.0) bin/unicorn:128:in `<top (required)>'
bin/unicorn:96:in `load'
bin/unicorn:96:in `block in <main>'
bin/unicorn:95:in `fork'
bin/unicorn:95:in `<main>'

```

// Full Trace

```plaintext
omniauth (1.9.2) lib/omniauth/failure_endpoint.rb:25:in `raise_out!'
omniauth (1.9.2) lib/omniauth/failure_endpoint.rb:20:in `call'
omniauth (1.9.2) lib/omniauth/failure_endpoint.rb:12:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:491:in `fail!'
/home/hardway/Downloads/omniauth-oauth2/lib/omniauth/strategies/oauth2.rb:88:in `callback_phase'
plugins/discourse-openid-connect/lib/omniauth_open_id_connect.rb:142:in `callback_phase'
omniauth (1.9.2) lib/omniauth/strategy.rb:238:in `callback_call'
omniauth (1.9.2) lib/omniauth/strategy.rb:189:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/strategy.rb:192:in `call!'
omniauth (1.9.2) lib/omniauth/strategy.rb:169:in `call'
omniauth (1.9.2) lib/omniauth/builder.rb:45:in `call'
lib/middleware/omniauth_bypass_middleware.rb:53:in `call'
rack (2.2.8) lib/rack/tempfile_reaper.rb:15:in `call'
rack (2.2.8) lib/rack/conditional_get.rb:27:in `call'
rack (2.2.8) lib/rack/head.rb:12:in `call'
actionpack (7.0.7) lib/action_dispatch/http/permissions_policy.rb:38:in `call'
lib/content_security_policy/middleware.rb:12:in `call'
lib/middleware/gtm_script_nonce_injector.rb:10:in `call'
rack (2.2.8) lib/rack/session/abstract/id.rb:266:in `context'
rack (2.2.8) lib/rack/session/abstract/id.rb:260:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/cookies.rb:704:in `call'
activerecord (7.0.7) lib/active_record/migration.rb:603:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/callbacks.rb:27:in `block in call'
activesupport (7.0.7) lib/active_support/callbacks.rb:99:in `run_callbacks'
actionpack (7.0.7) lib/action_dispatch/middleware/callbacks.rb:26:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/actionable_exceptions.rb:17:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/debug_exceptions.rb:28:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/show_exceptions.rb:29:in `call'
logster (2.13.0) lib/logster/middleware/reporter.rb:40:in `call'
railties (7.0.7) lib/rails/rack/logger.rb:40:in `call_app'
railties (7.0.7) lib/rails/rack/logger.rb:27:in `call'
config/initializers/100-quiet_logger.rb:20:in `call'
config/initializers/100-silence_logger.rb:29:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/remote_ip.rb:93:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/request_id.rb:26:in `call'
rack (2.2.8) lib/rack/method_override.rb:24:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/executor.rb:14:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/static.rb:23:in `call'
rack (2.2.8) lib/rack/sendfile.rb:110:in `call'
actionpack (7.0.7) lib/action_dispatch/middleware/host_authorization.rb:137:in `call'
lib/middleware/missing_avatars.rb:22:in `call'
lib/middleware/turbo_dev.rb:31:in `call'
rack-mini-profiler (3.1.1) lib/mini_profiler.rb:413:in `call'
message_bus (4.3.8) lib/message_bus/rack/middleware.rb:60:in `call'
railties (7.0.7) lib/rails/engine.rb:530:in `call'
railties (7.0.7) lib/rails/railtie.rb:226:in `public_send'
railties (7.0.7) lib/rails/railtie.rb:226:in `method_missing'
rack (2.2.8) lib/rack/urlmap.rb:74:in `block in call'
rack (2.2.8) lib/rack/urlmap.rb:58:in `each'
rack (2.2.8) lib/rack/urlmap.rb:58:in `call'
unicorn (6.1.0) lib/unicorn/http_server.rb:634:in `process_client'
unicorn (6.1.0) lib/unicorn/http_server.rb:739:in `worker_loop'
unicorn (6.1.0) lib/unicorn/http_server.rb:547:in `spawn_missing_workers'
unicorn (6.1.0) lib/unicorn/http_server.rb:143:in `start'
unicorn (6.1.0) bin/unicorn:128:in `<top (required)>'
bin/unicorn:96:in `load'
bin/unicorn:96:in `block in <main>'
bin/unicorn:95:in `fork'
bin/unicorn:95:in `<main>'

```

# Possible reason

- [Discourse OpenID Connect (OIDC) - #257](https://meta.discourse.org/t/discourse-openid-connect/103632/257)
- [google\_oauth2 Authentication failure! csrf\_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf\_detected | CSRF detected · Issue #58 · omniauth/omniauth-oauth2 · GitHub](https://github.com/omniauth/omniauth-oauth2/issues/58#issuecomment-55061098)
- …

# The guidance or tips I want to get

- How authentication in discourse works?
- How discourse uses session?
- Discourse messaging mechanism
- It would be best if you could tell me the solution directly

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [October 19, 2023, 7:34pm UTC](https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786/2 "2023-10-19T19:34:22Z")

</div>

> [@wayway\_way](#):
>
> OIDC connection configuration on keycloak
> 
> - Valid redirect URIs: `http://127.0.0.1:3000/auth/oidc/callback`

Possibly unrelated, but does setting the valid redirect URIs to `http://127.0.0.1:4200/auth/oidc/callback` make a difference?

Also, there’s currently something strange going on with the Ubuntu/Debian dev environment where the site can be accessed at either `localhost:4200` or `127.0.0.1:4200`. Each of those domains creates a separate session. Probably not related to your issue, but maybe something that could cause issues for local development. I always use the `localhost:4200` domain. That seems to be what’s expected.

---

<div class="post-metadata">

### Author: ![david](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/david/32/157490_2.png) [@david](https://meta.discourse.org/u/david)
#### Post date: [October 19, 2023, 10:17pm UTC](https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786/3 "2023-10-19T22:17:04Z")

</div>

> [@simon](#):
>
> does setting the valid redirect URIs to `http://127.0.0.1:4200/auth/oidc/callback` make a difference?

Yeah this would be my first thought as well. It’s important the authentication flow starts and ends on the same port, otherwise the session may be different.

If you boot Rails and Ember-CLI together via `bin/ember-cli -u`, then things should be automatically configured for you. But if you’re starting them separately, make sure you set the `DISCOURSE_PORT=4200` environment on the Rails server so that everything lines up correctly.

---

<div class="post-metadata">

### Author: ![wayway\_way](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wayway_way/32/327018_2.png) [@wayway\_way](https://meta.discourse.org/u/wayway_way)
#### Post date: [October 20, 2023, 3:57am UTC](https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786/4 "2023-10-20T03:57:11Z")

</div>

I tried, but “Invalid parameter: redirect\_uri” appears in Keycloak.

Boot Rails and Ember-CLI together via `bin/ember-cli -u`

 ![image](https://global.discourse-cdn.com/meta/original/4X/8/d/c/8dcc950e712b293a163cda10335952af06b655ec.png)

Set the valid redirect URIs to `http://127.0.0.1:4200/auth/oidc/callback`.

 ![image](https://global.discourse-cdn.com/meta/original/4X/9/6/f/96fca6daedc6b24097d820066964befd6bcc6753.png)

 ![image](https://global.discourse-cdn.com/meta/original/4X/8/e/2/8e24a8d899eb20c0bcd1127e66a25e883488f91d.png)

 ![image](https://global.discourse-cdn.com/meta/original/4X/c/f/d/cfdac7c0679e263050d30df2673b274efa620b76.jpeg)

---

<div class="post-metadata">

### Author: ![wayway\_way](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wayway_way/32/327018_2.png) [@wayway\_way](https://meta.discourse.org/u/wayway_way)
#### Post date: [October 20, 2023, 6:57am UTC](https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786/5 "2023-10-20T06:57:56Z")

</div>

It appears that the cause is a discrepancy between the valid redirect URIs in Keycloak and the URIs depicted in the following illustration.

> [@wayway\_way](#):
>
> ![image](https://global.discourse-cdn.com/meta/original/4X/c/f/d/cfdac7c0679e263050d30df2673b274efa620b76.jpeg)
> 
> image1920×901 145 KB

The URI depicted within the image is

```plaintext
http://127.0.0.1:8080/realms/mediawiki-realm/protocol/openid-connect/auth?client_id=mydiscourse&nonce=dce3dd8bccb09b25f88d1645d26b9d20b58e3d2ff3804f83ed79098c793a5ae2&redirect_uri=http%3A%2F%2F127.0.0.1%3A3000%2Fauth%2Foidc%2Fcallback&response_type=code&scope=openid+profile+email&state=7fd712dd2b28c8264eac170721b898b26ae8fb2edb9a2e9f

```

Upon decoding the ‘redirect\_uri’, its equivalence to

```plaintext
http://127.0.0.1:3000/auth/oidc/callback

```

What, indeed, ought to be the correct redirect\_uri?

---

<div class="post-metadata">

### Author: ![wayway\_way](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wayway_way/32/327018_2.png) [@wayway\_way](https://meta.discourse.org/u/wayway_way)
#### Post date: [October 20, 2023, 2:07pm UTC](https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786/6 "2023-10-20T14:07:41Z")

</div>

Would you be so kind as to divulge the platform utilized for identity verification during the creation of this plugin?

---

<div class="post-metadata">

### Author: ![wayway\_way](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/wayway_way/32/327018_2.png) [@wayway\_way](https://meta.discourse.org/u/wayway_way)
#### Post date: [October 23, 2023, 3:25am UTC](https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786/7 "2023-10-23T03:25:25Z")

</div>

> [@simon](#):
>
> Probably not related to your issue, but maybe something that could cause issues for local development. I always use the `localhost:4200` domain. That seems to be what’s expected

Thanks, it works. 😊  
My workaround was to open discourse using 127.0.0.1:4200 instead of localhost:4200

---

<div class="post-metadata">

### Author: ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)
#### Post date: [October 28, 2023, 7:34am UTC](https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786/8 "2023-10-28T07:34:25Z")

</div>

I’m not recommending it, but for local development I took the somewhat brutal approach of editing the plugin’s `callback_url` method: [discourse-openid-connect/lib/omniauth\_open\_id\_connect.rb at main · discourse/discourse-openid-connect · GitHub](https://github.com/discourse/discourse-openid-connect/blob/main/lib/omniauth_open_id_connect.rb#L218-L220).

```ruby
     def callback_url
        full_host = 'http://localhost:4200'
        full_host + script_name + callback_path
      end

```

That way it always returns `http://localhost:4200/auth/oidc/callback`

Without that change, I couldn’t find a way to get the host part of the URL set to anything other than `http://127.0.0.1:3000`

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [November 27, 2023, 7:34am UTC](https://meta.discourse.org/t/csrf-problem-in-development-with-discourse-openid-connect-plug-in/282786/9 "2023-11-27T07:34:41Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
