Setting up multiple Okta orgs with the same Omniauth Oauth2 Strategy in Rails
Hello There,
I want to share what I did in order to support a second Okta Organization in a Ruby on Rails application using omniauth_oktaoauth
gem.
I started with a basic spec to make sure I dont break anything:
RSpec.describe 'Sign in with Okta', type: :request do
describe "Using Okta" do
let(:user) { User.find_by email: user_email }
let(:okta_oauth) do
{
provider: okta_provider.to_s,
uid: "123456789",
info: {
name: "John Doe",
email: user_email,
}
}
end
before(:each) do
OmniAuth.config.test_mode = true
OmniAuth.config.mock_auth[okta_provider] = OmniAuth::AuthHash.new(okta_oauth)
end
context "When using existing configuration" do
let(:okta_provider) { :oktaoauth }
let(:user_email) { "john.okta@existing.domain" }
it "keeps working" do
post "/users/auth/oktaoauth"
follow_redirect!
expect(user.email).to eq(user_email)
end
end
end
end
With this, I proceed to write another spec to ensure the new option would work:
context "When using second okta org" do
let(:okta_provider) { :second_okta }
let(:user_email) { "john.okta@new.domain" }
it "signs the right user in" do
post "/users/auth/second_okta"
follow_redirect!
expect(user.email).to eq(user_email)
end
end
After this, I started to use the normal steps:
# user.rb
devise :omniauthable, omniauth_providers: [:oktaoauth, :second_okta]
Then, modify the initializer to tell omniauth about the new strategy
# config/initializers/okta.rb
....
config.omniauth(:second_okta,
Rails.configuration.second_okta.client_id,
Rails.configuration.second_okta.client_secret,
name: "second_okta",
request_path: "/users/auth/second_okta",
callback_path: "/users/auth/second_okta/callback",
scope: "openid profile email",
fields: %w[profile email],
client_options: {
site: Rails.configuration.second_okta.url,
authorize_url: "#{Rails.configuration.second_okta.auth_issuer}/v1/authorize",
token_url: "#{Rails.configuration.second_okta.auth_issuer}/v1/token"
},
redirect_uri: "#{Rails.configuration.app.base_domain}/users/auth/second_okta/callback",
issuer: Rails.configuration.second_okta.auth_issuer,
strategy_class: OmniAuth::Strategies::Oktaoauth)
At the beginning, it looked easy to add a second option using the same strategy, but after dealing with omniauth internals and omniauth_oktaoauth source code itself, I found that I needed to specify name
and strategy_class
to override defaults, there's something inside the source code that did not work out of the box, I had to specify request_path
and callback_path
explicitly (I'll dig deeper later and send a patch if it's a bug).
After making those changes, it worked just fine.
Thanks!