Commit b4ca282
Changed files (3)
app
controllers
spec
requests
app/controllers/responses_controller.rb
@@ -3,7 +3,12 @@
class ResponsesController < ApplicationController
def show
if session[:saml].present?
- saml = Saml::Kit::AuthenticationRequest.new(session[:saml][:xml])
+ xml = session[:saml][:xml]
+ saml = if session[:saml][:type] == 'authnrequest'
+ Saml::Kit::AuthenticationRequest.new(xml)
+ else
+ Saml::Kit::LogoutRequest.new(xml)
+ end
return render_error(:forbidden, model: saml) if saml.invalid?
post_back(saml, session[:saml][:params][:RelayState])
else
@@ -14,10 +19,24 @@ class ResponsesController < ApplicationController
private
def post_back(saml, relay_state)
- @url, @saml_params = saml.response_for(
- current_user, binding: :http_post, relay_state: relay_state
- ) do |builder|
- @saml_response_builder = builder
+ if saml.is_a?(Saml::Kit::AuthenticationRequest)
+ @url, @saml_params = saml.response_for(
+ current_user, binding: :http_post, relay_state: relay_state
+ ) do |builder|
+ @saml_response_builder = builder
+ end
+ user_id = current_user.to_param
+ mfa_issued_at = session[:mfa].present? ? session[:mfa][:issued_at] : nil
+ reset_session
+ session[:user_id] = user_id
+ session[:mfa] = { issued_at: mfa_issued_at } if mfa_issued_at.present?
+ else
+ @url, @saml_params = saml.response_for(
+ binding: :http_post, relay_state: relay_state
+ ) do |builder|
+ @saml_response_builder = builder
+ end
+ reset_session
end
end
end
app/controllers/sessions_controller.rb
@@ -18,7 +18,11 @@ class SessionsController < ApplicationController
)
@saml_request = binding.deserialize(saml_params)
if @saml_request.valid?
- session[:saml] = { params: saml_params.to_h, xml: @saml_request.to_xml }
+ session[:saml] = {
+ type: 'authnrequest',
+ params: saml_params.to_h,
+ xml: @saml_request.to_xml
+ }
return redirect_to response_path if current_user?
else
render_error(:forbidden, model: @saml_request)
@@ -44,13 +48,12 @@ class SessionsController < ApplicationController
saml = binding.deserialize(saml_params)
raise ActiveRecord::RecordInvalid.new(saml) if saml.invalid?
raise 'Unknown NameId' unless current_user.uuid == saml.name_id
-
- @url, @saml_params = saml.response_for(
- binding: :http_post, relay_state: saml_params[:RelayState]
- ) do |builder|
- @saml_response_builder = builder
- end
- reset_session
+ session[:saml] = {
+ type: 'logout_request',
+ params: saml_params.to_h,
+ xml: saml.to_xml
+ }
+ redirect_to response_path
elsif saml_params[:SAMLResponse].present?
saml = binding.deserialize(saml_params)
raise ActiveRecord::RecordInvalid.new(saml) if saml.invalid?
spec/requests/sessions_spec.rb
@@ -12,6 +12,12 @@ describe SessionsController do
before { Saml::Kit.configuration.registry = registry }
+ def session_id_from(response)
+ cookies = response.headers['Set-Cookie']
+ return if cookies.nil?
+ cookies.split("\;")[0].split("=")[1]
+ end
+
describe "POST /session/new" do
let(:post_binding) { Saml::Kit::Bindings::HttpPost.new(location: new_session_url) }
@@ -184,6 +190,7 @@ describe SessionsController do
context "when receiving a logout request" do
before :each do
http_login(user)
+ @session_id = session_id_from(response)
allow(registry).to receive(:metadata_for).with(issuer).and_return(sp_metadata)
builder = Saml::Kit::LogoutRequest.builder(user) do |x|
@@ -192,11 +199,14 @@ describe SessionsController do
end
url, saml_params = post_binding.serialize(builder)
post url, params: saml_params
+ follow_redirect!
end
specify { expect(response).to have_http_status(:ok) }
specify { expect(response.body).to include("SAMLResponse") }
specify { expect(response.body).to include(sp_metadata.single_logout_service_for(binding: :http_post).location) }
+ specify { expect(session_id_from(response)).to be_present }
+ specify { expect(session_id_from(response)).not_to eql(@session_id) }
end
context "when receiving a logout response" do
@@ -216,12 +226,6 @@ describe SessionsController do
context "when logging out of the IDP only" do
let(:user) { create(:user) }
- def session_id_from(response)
- cookies = response.headers['Set-Cookie']
- return if cookies.nil?
- cookies.split("\;")[0].split("=")[1]
- end
-
before :each do
http_login(user)
@session_id = session_id_from(response)