diff --git a/lib/omniauth/strategies/openid_connect.rb b/lib/omniauth/strategies/openid_connect.rb index 73dd0fe0..de28cf66 100644 --- a/lib/omniauth/strategies/openid_connect.rb +++ b/lib/omniauth/strategies/openid_connect.rb @@ -157,6 +157,12 @@ def callback_phase def other_phase if logout_path_pattern.match?(current_path) + + # Add the strategy and call the setup phase, so we can have a dynamic post_logout_redirect_uri + # This mimics what OmniAuth::Strategy does before the request_phase or callback_phase + @env['omniauth.strategy'] = self + setup_phase + options.issuer = issuer if options.issuer.to_s.empty? discover! return redirect(end_session_uri) if end_session_uri diff --git a/test/lib/omniauth/strategies/openid_connect_test.rb b/test/lib/omniauth/strategies/openid_connect_test.rb index ffa9f708..9f33ceb1 100644 --- a/test/lib/omniauth/strategies/openid_connect_test.rb +++ b/test/lib/omniauth/strategies/openid_connect_test.rb @@ -22,6 +22,7 @@ def test_request_phase def test_logout_phase_with_discovery expected_redirect = %r{^https://example\.com/logout$} + strategy.instance_variable_set(:@env, {}) strategy.options.client_options.host = 'example.com' strategy.options.discovery = true @@ -46,6 +47,7 @@ def test_logout_phase_with_discovery def test_logout_phase_with_discovery_and_post_logout_redirect_uri expected_redirect = 'https://example.com/logout?post_logout_redirect_uri=https%3A%2F%2Fmysite.com' + strategy.instance_variable_set(:@env, {}) strategy.options.client_options.host = 'example.com' strategy.options.discovery = true strategy.options.post_logout_redirect_uri = 'https://mysite.com' @@ -69,7 +71,36 @@ def test_logout_phase_with_discovery_and_post_logout_redirect_uri strategy.other_phase end + def test_logout_phase_with_discovery_and_dynamic_post_logout_redirect_uri + expected_redirect = 'https://example.com/logout?post_logout_redirect_uri=https%3A%2F%2Fmysite.com' + strategy.instance_variable_set(:@env, {}) + strategy.options.client_options.host = 'example.com' + strategy.options.discovery = true + strategy.options.setup = proc { |env| + env['omniauth.strategy'].options[:post_logout_redirect_uri] = 'https://mysite.com' + } + + issuer = stub('OpenIDConnect::Discovery::Issuer') + issuer.stubs(:issuer).returns('https://example.com/') + ::OpenIDConnect::Discovery::Provider.stubs(:discover!).returns(issuer) + + config = stub('OpenIDConnect::Discovery::Provder::Config') + config.stubs(:authorization_endpoint).returns('https://example.com/authorization') + config.stubs(:token_endpoint).returns('https://example.com/token') + config.stubs(:userinfo_endpoint).returns('https://example.com/userinfo') + config.stubs(:jwks_uri).returns('https://example.com/jwks') + config.stubs(:end_session_endpoint).returns('https://example.com/logout') + ::OpenIDConnect::Discovery::Provider::Config.stubs(:discover!).with('https://example.com/').returns(config) + + request.stubs(:path_info).returns('/auth/openid_connect/logout') + request.stubs(:path).returns('/auth/openid_connect/logout') + + strategy.expects(:redirect).with(expected_redirect) + strategy.other_phase + end + def test_logout_phase_with_logout_path + strategy.instance_variable_set(:@env, {}) strategy.options.issuer = 'example.com' strategy.options.client_options.host = 'example.com' strategy.options.logout_path = '/sign_out' @@ -81,6 +112,7 @@ def test_logout_phase_with_logout_path end def test_logout_phase + strategy.instance_variable_set(:@env, {}) strategy.options.issuer = 'example.com' strategy.options.client_options.host = 'example.com'