-
Notifications
You must be signed in to change notification settings - Fork 206
Description
Description:
Problem
When using Rails.application.config.middleware.use OmniAuth::Builder in an initializer as shown in the README and documentation, OmniAuth could be inserted in different places of the middleware stack. This could cause the automatic /auth/:provider routes to not work, resulting in ActionController::RoutingError (No route matches [GET] "/auth/:provider") or other failures.
Root Cause
When OmniAuth is at the end of the middleware stack, Rails routing middleware has already processed the request and raised a routing error before OmniAuth has a chance to intercept the /auth/:provider path.
Current Behavior
Following the documentation:
# config/initializers/omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
provider :saml, { ... }
endCould result in OmniAuth being placed improperly in the the middleware stack. Here is an example with our stack at my company:
Rails.application.middleware.each_with_index { |m, i| puts "#{i}: #{m}" }
=> #<ActionDispatch::MiddlewareStack:0x000000011639f5c8
@middlewares=
[Rack::Cors,
Datadog::Tracing::Contrib::Rack::TraceMiddleware,
SecureHeaders::Middleware,
ActionDispatch::HostAuthorization,
Rack::Sendfile,
ActionDispatch::Static,
ActionDispatch::Executor,
ActiveSupport::Cache::Strategy::LocalCache::Middleware,
Rack::Runtime,
Rack::MethodOverride,
ActionDispatch::RequestId,
RequestStore::Middleware,
ActionDispatch::RemoteIp,
ActionDispatch::ShowExceptions,
Sentry::Rails::CaptureExceptions,
WebConsole::Middleware,
ActionDispatch::DebugExceptions,
Datadog::Tracing::Contrib::Rails::ExceptionMiddleware,
Sentry::Rails::RescuedExceptionInterceptor,
ActionDispatch::ActionableExceptions,
ActionDispatch::Reloader,
ActionDispatch::Callbacks,
ActionDispatch::Cookies,
ActionDispatch::Session::CookieStore,
ActionDispatch::Flash,
ActionDispatch::ContentSecurityPolicy::Middleware,
Rack::Head,
Rack::ConditionalGet,
Rack::ETag,
Rack::TempfileReaper,
Warden::Manager,
RequestContextMiddleware,
Rack::Attack,
Sentry::Rack::CaptureExceptions,
Rack::Utm,
WickedPdf::Middleware,
ExceptionNotification::Rack,
ApolloUploadServer::Middleware,
OmniAuth::Builder]>
Accessing /auth/saml returns a 404.
Expected Behavior
OmniAuth should be positioned early enough in the middleware stack to intercept /auth/:provider requests before Rails routing processes them ; and after required middlewares (if there are any)
Proposed Solution
Update the documentation (README and/or guides) to:
- Recommend using
insert_beforeorinsert_afterwith a specific middleware as the default approach - Explain that
middleware.usecould append to the end of the stack in some situations and may not work in all Rails configurations - Provide guidance on appropriate middleware positioning (e.g., before session middleware but after security middleware)
Suggested Documentation Change
Current:
Rails.application.config.middleware.use OmniAuth::Builder do
provider :developer unless Rails.env.production?
endProposed:
Clarify which middlewares are needed (cookies, request store, etc), and suggest something like
# Place OmniAuth before session middleware to ensure it intercepts auth requests
Rails.application.config.middleware.insert_after X, OmniAuth::Builder do
provider :developer unless Rails.env.production?
end
# Alternative: use 'insert_after' with a specific middleware
# Rails.application.config.middleware.insert_after ActionDispatch::Cookies, OmniAuth::Builder do
# ...
# end
# Note: Using 'middleware.use' appends OmniAuth to the end of the stack,
# which may cause routing errors in some Rails configurations.Environment
- Rails version: 6.0.6.1
- OmniAuth version: omniauth-2.1.2
Additional Context
This issue is particularly confusing because:
- The callback routes (
/auth/:provider/callback) work fine when manually defined inroutes.rb - The middleware IS loaded (visible in
Rails.application.middleware) - The error message suggests a routing problem rather than a middleware ordering issue
- This affects SP-initiated flows where users need to start authentication by visiting
/auth/:provider