FIX: Correctly handle end_session_endpoint with query parameters (#18)

This commit is contained in:
David Taylor 2021-09-17 17:00:29 +01:00 committed by GitHub
parent cb3f891361
commit 5e1f1a57db
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 23 additions and 7 deletions

View File

@ -37,15 +37,23 @@ on(:before_session_destroy) do |data|
next next
end end
begin
uri = URI.parse(end_session_endpoint)
rescue URI::Error
authenticator.oidc_log "Logout: unable to parse end_session_endpoint #{end_session_endpoint}", error: true
end
authenticator.oidc_log "Logout: Redirecting user_id=#{data[:user].id} to end_session_endpoint" authenticator.oidc_log "Logout: Redirecting user_id=#{data[:user].id} to end_session_endpoint"
redirect_uri = end_session_endpoint params = URI.decode_www_form(String(uri.query))
redirect_uri += "?id_token_hint=#{token}"
params << ["id_token_hint", token]
post_logout_redirect = SiteSetting.openid_connect_rp_initiated_logout_redirect.presence post_logout_redirect = SiteSetting.openid_connect_rp_initiated_logout_redirect.presence
redirect_uri += "&post_logout_redirect_uri=#{post_logout_redirect}" if post_logout_redirect params << ["post_logout_redirect_uri", post_logout_redirect] if post_logout_redirect
data[:redirect_url] = redirect_uri uri.query = URI.encode_www_form(params)
data[:redirect_url] = uri.to_s
end end
auth_provider authenticator: OpenIDConnectAuthenticator.new auth_provider authenticator: OpenIDConnectAuthenticator.new

View File

@ -11,14 +11,14 @@ describe "OIDC RP-Initiated Logout" do
"token_endpoint": "https://id.example.com/token", "token_endpoint": "https://id.example.com/token",
"userinfo_endpoint": "https://id.example.com/userinfo", "userinfo_endpoint": "https://id.example.com/userinfo",
"end_session_endpoint": "https://id.example.com/endsession", "end_session_endpoint": "https://id.example.com/endsession",
}.to_json }
end end
let(:user) { Fabricate(:user) } let(:user) { Fabricate(:user) }
before do before do
SiteSetting.openid_connect_enabled = true SiteSetting.openid_connect_enabled = true
SiteSetting.openid_connect_rp_initiated_logout = true SiteSetting.openid_connect_rp_initiated_logout = true
stub_request(:get, document_url).to_return(body: document) stub_request(:get, document_url).to_return(body: lambda { |r| document.to_json })
end end
after do after do
@ -52,11 +52,19 @@ describe "OIDC RP-Initiated Logout" do
expect(response.parsed_body["redirect_url"]).to eq("https://id.example.com/endsession?id_token_hint=myoidctoken") expect(response.parsed_body["redirect_url"]).to eq("https://id.example.com/endsession?id_token_hint=myoidctoken")
end end
it "correctly handles logout urls with existing query params" do
document[:end_session_endpoint] += "?param=true"
delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("https://id.example.com/endsession?param=true&id_token_hint=myoidctoken")
end
it "includes the redirect URI if set" do it "includes the redirect URI if set" do
SiteSetting.openid_connect_rp_initiated_logout_redirect = "https://example.com" SiteSetting.openid_connect_rp_initiated_logout_redirect = "https://example.com"
delete "/session/#{user.username}", xhr: true delete "/session/#{user.username}", xhr: true
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response.parsed_body["redirect_url"]).to eq("https://id.example.com/endsession?id_token_hint=myoidctoken&post_logout_redirect_uri=https://example.com") expect(response.parsed_body["redirect_url"]).to eq("https://id.example.com/endsession?id_token_hint=myoidctoken&post_logout_redirect_uri=https%3A%2F%2Fexample.com")
end end
it "does not redirect if plugin disabled" do it "does not redirect if plugin disabled" do