Commit c44dca3
2017-11-19 17:53:48
1 parent
fa0ad10
Changed files (8)
airport
app
controllers
models
views
sessions
proof
app
saml-kit
lib
saml
kit
locales
airport/app/controllers/metadata_controller.rb
@@ -9,11 +9,7 @@ class MetadataController < ApplicationController
def to_xml
Rails.cache.fetch(metadata_url, expires_in: 1.hour) do
- builder = Saml::Kit::ServiceProviderMetadata::Builder.new
- builder.sign = false
- builder.add_assertion_consumer_service(session_url, binding: :post)
- builder.add_single_logout_service(session_url, binding: :post)
- builder.to_xml
+ Sp.default(request).to_xml
end
end
end
airport/app/controllers/sessions_controller.rb
@@ -21,7 +21,8 @@ class SessionsController < ApplicationController
end
def create
- @saml_response = Saml::Kit::Response.deserialize(params[:SAMLResponse])
+ saml_binding = 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)
@@ -29,9 +30,15 @@ class SessionsController < ApplicationController
end
def destroy
- @post_uri = idp_metadata.single_logout_service_for(binding: :post)
- @saml_request = Saml::Kit::LogoutRequest::Builder.new(current_user, sign: true).build.serialize
- render layout: "spinner"
+ if params['SAMLRequest'].present?
+ redirect_to new_session_path
+ else
+ saml_binding = idp_metadata.single_logout_service_for(binding: :post)
+ builder = Saml::Kit::LogoutRequest::Builder.new(current_user, sign: true)
+ @url, @saml_params = saml_binding.serialize(builder)
+ reset_session
+ render layout: "spinner"
+ end
end
private
@@ -39,4 +46,13 @@ class SessionsController < ApplicationController
def idp_metadata
Rails.configuration.x.idp_metadata
end
+
+ def binding_for(request)
+ target_binding = request.post? ? :post : :http_redirect
+ sp.single_logout_service_for(binding: target_binding)
+ end
+
+ def sp
+ Sp.default(request)
+ end
end
airport/app/models/sp.rb
@@ -0,0 +1,15 @@
+class Sp
+ class << self
+ def default(request)
+ @sp ||= begin
+ url_helpers = Rails.application.routes.url_helpers
+ 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_single_logout_service(url_helpers.session_url(host: host), binding: :post)
+ builder.build
+ end
+ end
+ end
+end
airport/app/views/sessions/destroy.html.erb
@@ -1,6 +1,8 @@
-<%= form_tag(@post_uri, style: "position: absolute; left: -10000px; top: -10000px;") do %>
- <%= hidden_field_tag("SAMLRequest", @saml_request) %>
- <%= submit_tag "Submit" %>
+<h1>Loggout out of SP</h1>
+<%= form_tag(@url, style: "position: absolute; left: -10000px; top: -10000px;") do %>
+ <%= @saml_params.each do |(key, value)| %>
+ <%= hidden_field_tag key, value %>
+ <% end %>
<% end %>
<%= javascript_tag do %>
proof/app/controllers/sessions_controller.rb
@@ -21,8 +21,9 @@ class SessionsController < ApplicationController
def destroy
user = User.find_by(uuid: @saml_request.name_id)
- @saml_response = @saml_request.response_for(user)
- @relay_state = params[:RelayState]
+
+ saml_binding = binding_for(request)
+ @url, @saml_params = saml_binding.serialize(@saml_request.response_for(user), relay_state: params[:RelayState])
reset_session
render layout: "spinner"
end
proof/app/models/idp.rb
@@ -22,7 +22,7 @@ class Idp
builder.attributes << :email
builder.attributes << :created_at
builder.build
- end
+ end
end
end
end
proof/app/views/sessions/destroy.html.erb
@@ -1,8 +1,8 @@
<h1>Logging Out of IDP</h1>
-<%= form_tag(@saml_response.destination, style: "position: absolute; left: -10000px; top: -10000px;") do %>
- <%= hidden_field_tag("SAMLResponse", @saml_response.serialize) %>
- <%= hidden_field_tag("RelayState", @relay_state) %>
- <%= submit_tag "Submit" %>
+<%= form_tag(@url, style: "position: absolute; left: -10000px; top: -10000px;") do %>
+ <%= @saml_params.each do |(key, value)| %>
+ <%= hidden_field_tag key, value %>
+ <% end %>
<% end %>
<%= javascript_tag do %>
saml-kit/lib/saml/kit/locales/en.yml
@@ -6,14 +6,13 @@ en:
invalid: "must contain AuthnRequest."
invalid_fingerprint: "does not match."
unregistered: "is unregistered."
- SPSSODescriptor:
- invalid: "must contain SPSSODescriptor."
- invalid_signature: "invalid signature."
IDPSSODescriptor:
invalid: "must contain IDPSSODescriptor."
invalid_signature: "invalid signature."
InvalidDocument:
invalid: "must contain valid SAMLRequest"
+ LogoutResponse:
+ unregistered: "is unregistered."
Response:
invalid: "must contain Response."
unregistered: "must originate from registered identity provider."
@@ -21,3 +20,6 @@ en:
invalid_version: "must be 2.0."
invalid_response_to: "must match request id."
must_match_issuer: "must match entityId."
+ SPSSODescriptor:
+ invalid: "must contain SPSSODescriptor."
+ invalid_signature: "invalid signature."