omniauth_openid_connect
omniauth_openid_connect copied to clipboard
OmniAuth::Strategies::OpenIDConnect::CallbackError, csrf_detected | Invalid 'state' parameter
Hi,
I am trying to configure omniauth_openid_connect to work with Devise and Microsoft Azure AD. I have the following config for devise
# config/initializers/devise.rb
config.omniauth :openid_connect, {
issuer: "https://login.microsoftonline.com/#{Rails.application.credentials.azure.tenant_id}/v2.0",
scope: [:openid],
response_type: :code,
response_mode: :form_post,
uid_field: "preferred_username",
discovery: true,
state: Proc.new { SecureRandom.hex(32) },
client_options: {
port: 443,
scheme: "https",
host: "login.microsoftonline.com/#{Rails.application.credentials.azure.tenant_id}/v2.0",
identifier: Rails.application.credentials.azure.client_id,
redirect_uri: "http://localhost:3000/users/auth/openid_connect/callback",
},
}
When attempting to authenticate, I see the following errors in my rails log
web.1 | Started POST "/users/auth/openid_connect" for ::1 at 2023-05-16 11:36:50 +0100
web.1 | D, [2023-05-16T11:36:50.593978 #78216] DEBUG -- omniauth: (openid_connect) Request phase initiated.
web.1 | Started POST "/users/auth/openid_connect/callback" for ::1 at 2023-05-16 11:36:51 +0100
web.1 | D, [2023-05-16T11:36:51.046305 #78216] DEBUG -- omniauth: (openid_connect) Callback phase initiated.
web.1 | E, [2023-05-16T11:36:51.046843 #78216] ERROR -- omniauth: (openid_connect) Authentication failure! csrf_detected: OmniAuth::Strategies::OpenIDConnect::CallbackError, csrf_detected | Invalid 'state' parameter
web.1 | Processing by Users::OmniauthCallbacksController#failure as HTML
web.1 | Parameters: {"code"=>"filtered", "state"=>"filtered", "session_state"=>"filtered"}
web.1 | Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 599)
web.1 |
web.1 |
web.1 | E, [2023-05-16T11:36:51.059259 #78216] ERROR -- omniauth: (openid_connect) Authentication failure! The browser returned a 'null' origin for a request with origin-based forgery protection turned on. This usually
web.1 | means you have the 'no-referrer' Referrer-Policy header enabled, or that the request came from a site that
web.1 | refused to give its origin. This makes it impossible for Rails to verify the source of the requests. Likely the
web.1 | best solution is to change your referrer policy to something less strict like same-origin or strict-origin.
web.1 | If you cannot change the referrer policy, you can disable origin checking with the
web.1 | Rails.application.config.action_controller.forgery_protection_origin_check setting.
Adding skip_forgery_protection
to my OmniauthCallbacksController
results in just the csrf error
web.1 | Started POST "/users/auth/openid_connect" for ::1 at 2023-05-16 11:32:19 +0100
web.1 | D, [2023-05-16T11:32:19.340738 #78216] DEBUG -- omniauth: (openid_connect) Request phase initiated.
web.1 | Started POST "/users/auth/openid_connect/callback" for ::1 at 2023-05-16 11:32:22 +0100
web.1 | D, [2023-05-16T11:32:22.146487 #78216] DEBUG -- omniauth: (openid_connect) Callback phase initiated.
web.1 | E, [2023-05-16T11:32:22.147050 #78216] ERROR -- omniauth: (openid_connect) Authentication failure! csrf_detected: OmniAuth::Strategies::OpenIDConnect::CallbackError, csrf_detected | Invalid 'state' parameter
web.1 | Processing by Users::OmniauthCallbacksController#failure as HTML
web.1 | Parameters: {"code"=>"filtered", "state"=>"filtered", "session_state"=>"filtered"}
web.1 | Redirected to http://localhost:3000/
web.1 | Completed 302 Found in 2ms (ActiveRecord: 0.0ms | Allocations: 504)
Can anyone offer me any guidance?
Thanks, Neil
What SameSite-config do you have?
We ran into errors like this after upgrading to Samesite=lax. Found the reason in this blog post: https://www.ubisecure.com/technical-announcements/samesite-cookies-changes/
Caution: unless some of the OIDC integrations are using response_mode=form_post
So if Microsoft Azure AD supports other response_modes I would suggest removing response_mode=form_post
.
Are you using the gem omniauth-rails_csrf_protection, or have you included something like this? It's needed when using omniauth v2. I remember getting some csrf related errors and adding the gem, plus the skip_forgery_protection
, and that seemed to solve them.
Might not be the same though, I'm not using the same provider.
I had the same issue in development, but it was my fault and super easy to fix: I was using "http://127.0.0.1:3000/..." when accessing my app but the callback had to point to a domain, so I had to use "http://localhost:3000/..." for it. This of course doesn't work, because the cookie that contains the state gets lost when the domain is switched by the redirect happening in the callback. Simply always using "http://localhost:3000/..." fixed the issue for me.