mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
FEATURE: Allow admins to opt-in to seamless redirects on /auth/*
(#31235)
By default, when multiple login providers are enabled, Discourse requires user interaction before triggering an external auth flow. This is defense-in-depth against "Login CSRF" attacks. This commit introduces a setting to control this behavior, so that it can be disabled when admins fully trust the downstream systems, and need an interaction-free login flow on a site with multiple login providers. Default behavior remains unchanged.
This commit is contained in:
@@ -1989,6 +1989,7 @@ en:
|
||||
|
||||
auth_skip_create_confirm: When signing up via external auth, skip the create account popup. Best used alongside auth_overrides_email, auth_overrides_username and auth_overrides_name.
|
||||
auth_immediately: "Automatically redirect to the external login system without user interaction. This only takes effect when login_required is true, and there is only one external authentication method"
|
||||
auth_require_interaction: "Require user interaction before redirecting to an external login system via `/auth/*`. This is defense-in-depth against 'Login CSRF' attacks. Only disable this setting if you fully trust all enabled auth methods are protected against login CSRF."
|
||||
|
||||
enable_discourse_connect: "Enable sign on via DiscourseConnect (formerly 'Discourse SSO') (WARNING: USERS' EMAIL ADDRESSES *MUST* BE VALIDATED BY THE EXTERNAL SITE!)"
|
||||
verbose_discourse_connect_logging: "Log verbose DiscourseConnect related diagnostics to <a href='%{base_path}/logs' target='_blank'>/logs</a>"
|
||||
|
@@ -606,6 +606,7 @@ login:
|
||||
client: true
|
||||
auth_overrides_username: false
|
||||
auth_overrides_name: false
|
||||
auth_require_interaction: true
|
||||
enable_discourse_connect:
|
||||
client: true
|
||||
default: false
|
||||
|
@@ -31,7 +31,10 @@ class Middleware::OmniauthBypassMiddleware
|
||||
# When only one provider is enabled, assume it can be completely trusted, and allow GET requests
|
||||
only_one_provider =
|
||||
!SiteSetting.enable_local_logins && Discourse.enabled_authenticators.length == 1
|
||||
OmniAuth.config.allowed_request_methods = only_one_provider ? %i[get post] : [:post]
|
||||
|
||||
allow_get = only_one_provider || !SiteSetting.auth_require_interaction
|
||||
|
||||
OmniAuth.config.allowed_request_methods = allow_get ? %i[get post] : [:post]
|
||||
|
||||
omniauth =
|
||||
OmniAuth::Builder.new(@app) do
|
||||
|
@@ -159,6 +159,13 @@ RSpec.describe Users::OmniauthCallbacksController do
|
||||
get "/auth/google_oauth2"
|
||||
expect(response.status).to eq(302)
|
||||
end
|
||||
|
||||
it "should not be CSRF protected if the setting has been disabled" do
|
||||
SiteSetting.auth_require_interaction = false
|
||||
SiteSetting.enable_local_logins = true
|
||||
get "/auth/google_oauth2"
|
||||
expect(response.status).to eq(302)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
Reference in New Issue
Block a user