Discourse の Discourse-oauth2-basic プラグインを設定して、ユーザーが NeonCRM で作成・保存されたアカウント認証情報を使って Discourse フォーラムにログインできるようにしようとしています。
NeonCRM のサポート技術者は、以下の形式を使って認証 URL を手動で作成できることを説明してくれました。
https://{{Org ID}}.z2systems.com/np/oauth/auth?response_type=code&client_id={{Client ID}}&redirect_uri={{Redirect URL}}
Discourse 側では、プラグインに対して以下のパラメータを設定しました。
oauth2 client id: MY-CLIENT-ID
oauth2 client secret: MY-CLIENT-SECRET
oauth2 authorize url: https://MY-NEON-ID.z2systems.com/np/oauth/auth
oauth2 token url: https://www.z2systems.com/np/oauth/token
そのため、以下のように URL を手動で作成しました(一部は伏字にしています)。
https://MY-NEON-ID.z2systems.com/np/oauth/auth?response_type=code&client_id=MY-CLIENT-ID&redirect_uri=https://MY-FORUM.COM/auth/oauth2_basic/callback
この URL をブラウザで開くと、Discourse のページが表示され、以下のようなメッセージが表示されます。
また、ログには以下のように記録されています。
(oauth2_basic) Authentication failure! csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF detected
なぜでしょうか?
つまり、この URL を代わりに使ってみると:
https://MY-NEON-ID.z2systems.com/np/oauth/auth?response_type=code&client_id=MY-CLIENT-ID&redirect_uri=https://MY-FORUM.COM/
(redirect_uri の末尾にあるコールバック部分を削除しました)
実際に NeonCRM のログインページに到達し、そこでテストユーザーの認証情報を入力してログインします。その後、MY-FORUM.COM にリダイレクトされますが、そこに到達してもログイン状態にはなっていません。ページの上部にある「Login」ボタンをクリックし、灰色の「login with OAuth2」ボタンをクリックすると、新しいウィンドウが開き、以下のメッセージが表示されます:
また、ログには以下の 2 つのエラーが表示されます:
ArgumentError (Invalid URI: )
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/excon-0.64.0/lib/excon.rb:126:in `new’
および
Failed to handle exception in exception app middleware : Invalid URI:
Falco
(Falco)
8
この redirect_uri は正しくありません。フローが機能するように、正しく設定する必要があります。
プラグインのドキュメントでは、基本設定の最初の項目として記載されています。
NeonCRM でも、公式ドキュメントで設定方法が説明されています。
@Falco さん、ありがとうございます!
redirect_uri を以下に設定しようと試みました:
https://MY-FORUM.COM/auth/oauth2_basic/callback
しかし、うまくいきませんでした。元の投稿(混乱を避けるために先ほど編集しました。見逃していたらすみません)をご確認ください。
Falco
(Falco)
10
あなたのフォーラムは HTTPS で動作していますか?
@Falco さん、force_https を有効にする手順を見つけ、true に設定しました。
しかし、同じエラーが発生したままです。
NeonCRM が推奨するウィジェットをフォーラムの上部に統合しました(必要であれば、ご自身でお試しください)。
https://forum.efao.ca/
このウィジェットを使用すると、元の投稿と同じ結果が表示されます。
(oauth2_basic) 認証に失敗しました!csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF が検出されました
どなたかいますか?@david さんか @Falco さん?
david
(David Taylor)
16
oauth2 プラグインで Excon を使用するのは、ここだけです。
oauth2_user_json_url に何を設定していますか?おそらく空白になっていると思われます。もしそうであれば、Discourse が空白の URL にアクセスしようとするのを防ぐため、oauth2_fetch_user_details も無効にする必要があります。
@david さん、確かに空ですね。
oauth2_user_json_url に何を設定すればよいか分かりません。残念ながら、NeonCRM のテクニカルサポートを通じてこれを特定しようとしましたが、うまくいきませんでした。
無効化しようとすると、「oauth2 callback user id path を設定する必要がある」というメッセージが表示されますが、前述の通り、この値が何であるべきか分かりません。
david
(David Taylor)
18
NeonCRM のインストール環境を持っていないためテストはできませんが、access_token に設定すれば動作すると思います。試してみてください。
上記の Falco さんがリンクしたドキュメントより:
同じエラー:
(oauth2_basic) 認証失敗!csrf_detected: OmniAuth::Strategies::OAuth2::CallbackError, csrf_detected | CSRF が検出されました
バックトレース:
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.3.2/lib/logster/logger.rb:110:in `report_to_store'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.3.2/lib/logster/logger.rb:101:in `add_with_opts'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.3.2/lib/logster/logger.rb:52:in `add'
/usr/local/lib/ruby/2.6.0/logger.rb:543:in `error'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:163:in `log'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:486:in `fail!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-oauth2-1.6.0/lib/omniauth/strategies/oauth2.rb:71:in `callback_phase'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:238:in `callback_call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:189:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:192:in `call!'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/strategy.rb:169:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/omniauth-1.9.0/lib/omniauth/builder.rb:64:in `call'
/var/www/discourse/lib/middleware/omniauth_bypass_middleware.rb:30:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/tempfile_reaper.rb:15:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/conditional_get.rb:25:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/head.rb:12:in `call'
/var/www/discourse/lib/content_security_policy/middleware.rb:12:in `call'
/var/www/discourse/lib/middleware/anonymous_cache.rb:218:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:232:in `context'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/session/abstract/id.rb:226:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/cookies.rb:670:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/callbacks.rb:28:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:98:in `run_callbacks'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/callbacks.rb:26:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/debug_exceptions.rb:61:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/show_exceptions.rb:33:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/logster-2.3.2/lib/logster/middleware/reporter.rb:43:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/rack/logger.rb:38:in `call_app'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/rack/logger.rb:28:in `call'
/var/www/discourse/config/initializers/100-quiet_logger.rb:18:in `call'
/var/www/discourse/config/initializers/100-silence_logger.rb:31:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/remote_ip.rb:81:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/request_id.rb:27:in `call'
/var/www/discourse/lib/middleware/enforce_hostname.rb:17:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/method_override.rb:22:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/actionpack-5.2.3/lib/action_dispatch/middleware/executor.rb:14:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/sendfile.rb:111:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-mini-profiler-1.1.0/lib/mini_profiler/profiler.rb:184:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/message_bus-2.2.0/lib/message_bus/rack/middleware.rb:57:in `call'
/var/www/discourse/lib/middleware/request_tracker.rb:163:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/engine.rb:524:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/railtie.rb:190:in `public_send'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/railties-5.2.3/lib/rails/railtie.rb:190:in `method_missing'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:68:in `block in call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `each'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rack-2.0.7/lib/rack/urlmap.rb:53:in `call'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:605:in `process_client'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:700:in `worker_loop'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:548:in `spawn_missing_workers'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/lib/unicorn/http_server.rb:144:in `start'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/unicorn-5.5.1/bin/unicorn:128:in `<top (required)>'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `load'
/var/www/discourse/vendor/bundle/ruby/2.6.0/bin/unicorn:23:in `<main>'
david
(David Taylor)
20
興味深いですね…バックトレースから、このエラーは OAuth2 ライブラリの この部分 に起因していることがわかります。つまり、state パラメータが正しく一致していないということです。
確認ですが、このエラーは あなたの本番サイト から発生したものでしょうか?私はそのサイトにログインを試みましたが、私の環境では state が正しく受け渡されているように見えます。
これはサーバー側の何らかの問題を示唆しています。サイトはどのようにホストされていますか?当社の 標準手順 に従いましたか?
@david さん、これも関連しているかどうかわかりませんが、私たちのログには以下のような別のエントリーもあります。
Job exception: SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate)
私たちは SSL 証明書に Let’sEncrypt を使用しています。
はい、forum.efao.ca が私たちの本番サイトです。Digital Ocean でホストされており、標準手順に従ってインストールされました。
/usr/local/lib/ruby/2.6.0/net/protocol.rb:44:in `connect_nonblock'
/usr/local/lib/ruby/2.6.0/net/protocol.rb:44:in `ssl_socket_connect'
/usr/local/lib/ruby/2.6.0/net/pop.rb:553:in `do_start'
/usr/local/lib/ruby/2.6.0/net/pop.rb:531:in `start'
/var/www/discourse/app/jobs/scheduled/poll_mailbox.rb:43:in `poll_pop3'
/var/www/discourse/app/jobs/scheduled/poll_mailbox.rb:18:in `execute'
/var/www/discourse/app/jobs/base.rb:232:in `block (2 levels) in perform'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/rails_multisite-2.0.7/lib/rails_multisite/connection_management.rb:63:in `with_connection'
/var/www/discourse/app/jobs/base.rb:221:in `block in perform'
/var/www/discourse/app/jobs/base.rb:217:in `each'
/var/www/discourse/app/jobs/base.rb:217:in `perform'
/var/www/discourse/app/jobs/base.rb:279:in `perform'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/mini_scheduler-0.11.0/lib/mini_scheduler/manager.rb:83:in `process_queue'
/var/www/discourse/vendor/bundle/ruby/2.6.0/gems/mini_scheduler-0.11.0/lib/mini_scheduler/manager.rb:34:in `block in initialize'
david
(David Taylor)
25
サーバーへのアクセスがないため、これ以上の診断は難しい恐怕です。oauth2 プラグインは多くのユーザーが問題なく利用していますので、どこかに設定上の問題があると考えられます。唯一考えられる対策は、安定版ブランチではなく、Discourse の最新バージョンにアップグレードすることです。
コミュニティの他の誰かが対応してくれるかもしれませんが、そうでない場合は、Marketplace で助けを求めてみるとよいかもしれません。