Commit 2c3c34e

mo <mo.khan@gmail.com>
2017-11-21 02:11:54
extract assertions controller for consuming responses from the IDP.
1 parent 33762c5
Changed files (5)
airport/app/controllers/assertions_controller.rb
@@ -0,0 +1,31 @@
+class AssertionsController < ApplicationController
+  skip_before_action :verify_authenticity_token, only: [:create, :destroy]
+  skip_before_action :authenticate!, only: [:create, :destroy]
+
+  def create
+    saml_binding = sp.assertion_consumer_service_for(binding: :post)
+    saml_response = saml_binding.deserialize(params)
+    return render :error, status: :forbidden if saml_response.invalid?
+
+    session[:user] = { id: saml_response.name_id }.merge(saml_response.attributes)
+    redirect_to dashboard_path
+  end
+
+  def destroy
+    if params['SAMLRequest'].present?
+      # IDP initiated logout
+    elsif params['SAMLResponse'].present?
+      saml_binding = sp.single_logout_service_for(binding: :post)
+      saml_response = saml_binding.deserialize(params)
+      raise ActiveRecordRecordInvalid.new(saml_response) if saml_response.invalid?
+      reset_session
+      redirect_to new_session_path
+    end
+  end
+
+  private
+
+  def sp
+    Sp.default(request)
+  end
+end
airport/app/controllers/sessions_controller.rb
@@ -1,48 +1,25 @@
 class SessionsController < ApplicationController
-  skip_before_action :verify_authenticity_token, only: [:create, :destroy]
-  skip_before_action :authenticate!
+  skip_before_action :authenticate!, only: [:new]
 
   def new
-    builder = Saml::Kit::AuthenticationRequest::Builder.new
-    @relay_state = JSON.generate(redirect_to: '/')
     # HTTP Redirect
     # * URI
     # * SigAlg
     # * Signature
     # * RelayState
     redirect_binding = idp.single_sign_on_service_for(binding: :http_redirect)
-    @redirect_uri, _ = redirect_binding.serialize(builder, relay_state: @relay_state)
+    @redirect_uri, _ = redirect_binding.serialize(builder_for(:login), relay_state: relay_state)
     # HTTP POST
     # * URI
     # * SAMLRequest/SAMLResponse
     post_binding = idp.single_sign_on_service_for(binding: :post)
-    @post_uri, @saml_params = post_binding.serialize(builder, relay_state: @relay_state)
-  end
-
-  def create
-    saml_binding = request_binding_for(request)
-    @saml_response = saml_binding.deserialize(params)
-    return render :error, status: :forbidden if @saml_response.invalid?
-
-    session[:user] = { id: @saml_response.name_id }.merge(@saml_response.attributes)
-    redirect_to dashboard_path
+    @post_uri, @saml_params = post_binding.serialize(builder_for(:login), relay_state: relay_state)
   end
 
   def destroy
-    if params['SAMLRequest'].present?
-      # IDP initiated logout
-    elsif params['SAMLResponse'].present?
-      saml_binding = request_binding_for(request)
-      saml_response = saml_binding.deserialize(params)
-      raise ActiveRecordRecordInvalid.new(saml_response) if saml_response.invalid?
-      reset_session
-      redirect_to new_session_path
-    else
-      saml_binding = idp.single_logout_service_for(binding: :post)
-      builder = Saml::Kit::LogoutRequest::Builder.new(current_user, sign: true)
-      @url, @saml_params = saml_binding.serialize(builder)
-      render layout: "spinner"
-    end
+    saml_binding = idp.single_logout_service_for(binding: :post)
+    @url, @saml_params = saml_binding.serialize(builder_for(:logout))
+    render layout: "spinner"
   end
 
   private
@@ -51,12 +28,16 @@ class SessionsController < ApplicationController
     Rails.configuration.x.idp_metadata
   end
 
-  def request_binding_for(request)
-    target_binding = request.post? ? :post : :http_redirect
-    sp.single_logout_service_for(binding: target_binding)
+  def relay_state
+    JSON.generate(redirect_to: '/')
   end
 
-  def sp
-    Sp.default(request)
+  def builder_for(type)
+    case type
+    when :login
+      Saml::Kit::AuthenticationRequest::Builder.new
+    when :logout
+      Saml::Kit::LogoutRequest::Builder.new(current_user)
+    end
   end
 end
airport/app/models/sp.rb
@@ -6,7 +6,7 @@ class Sp
         host = "#{request.protocol}#{request.host}:#{request.port}"
         builder = Saml::Kit::ServiceProviderMetadata::Builder.new
         builder.sign = false
-        builder.add_assertion_consumer_service(url_helpers.session_url(host: host), binding: :post)
+        builder.add_assertion_consumer_service(url_helpers.consume_url(host: host), binding: :post)
         builder.add_single_logout_service(url_helpers.logout_url(host: host), binding: :post)
         builder.build
       end
airport/app/views/sessions/error.html.erb → airport/app/views/assertions/error.html.erb
File renamed without changes
airport/config/routes.rb
@@ -1,7 +1,9 @@
 Rails.application.routes.draw do
   get "dashboard", to: "dashboard#show", as: :dashboard
   resource :session, only: [:new, :create, :destroy]
-  post "/session/logout" => "sessions#destroy", as: :logout
+  resource :assertion, only: [:create, :destroy]
+  post "/assertions/consume" => "assertions#create", as: :consume
+  post "/assertions/logout" => "assertions#destroy", as: :logout
   resource :metadata, only: [:show]
   resources :computers, only: [:index]
   root to: "sessions#new"