Commit 9b91421
Changed files (6)
lib
spec
saml
lib/saml/kit/authentication_request.rb
@@ -20,6 +20,10 @@ module Saml
@hash = Hash.from_xml(@content)
end
+ def query_string_parameter
+ 'SAMLRequest'
+ end
+
def id
to_h[name]['ID']
end
@@ -29,7 +33,11 @@ module Saml
end
def acs_url
- to_h[name]['AssertionConsumerServiceURL'] || registered_acs_url
+ #if signed? && trusted?
+ to_h[name]['AssertionConsumerServiceURL'] || registered_acs_url
+ #else
+ #registered_acs_url
+ #end
end
def issuer
lib/saml/kit/logout_request.rb
@@ -19,6 +19,10 @@ module Saml
@xml_hash = Hash.from_xml(xml)
end
+ def query_string_parameter
+ 'SAMLRequest'
+ end
+
def id
to_h[name]['ID']
end
lib/saml/kit/logout_response.rb
@@ -1,4 +1,3 @@
-
module Saml
module Kit
class LogoutResponse
@@ -10,6 +9,10 @@ module Saml
@xml_hash = Hash.from_xml(xml)
end
+ def query_string_parameter
+ 'SAMLResponse'
+ end
+
def id
to_h[name]['ID']
end
lib/saml/kit/response.rb
@@ -26,6 +26,10 @@ module Saml
@request_id = request_id
end
+ def query_string_parameter
+ 'SAMLResponse'
+ end
+
def id
to_h.fetch(name, {}).fetch('ID', nil)
end
lib/saml/kit/url_builder.rb
@@ -1,16 +1,16 @@
module Saml
module Kit
class UrlBuilder
- def build(request, binding:, relay_state: nil)
+ def build(saml_document, binding:, relay_state: nil)
payload = {
- 'SAMLRequest' => Content.encode_raw_saml(request.to_xml),
+ saml_document.query_string_parameter => Content.encode_raw_saml(saml_document.to_xml),
'RelayState' => relay_state,
'SigAlg' => Saml::Kit::Namespaces::SHA256,
}.map do |(x, y)|
"#{x}=#{y}"
end.join('&')
payload = URI.encode(payload)
- "#{request.destination}?#{payload}&Signature=#{signature_for(payload)}"
+ "#{saml_document.destination}?#{payload}&Signature=#{signature_for(payload)}"
end
private
spec/saml/url_builder_spec.rb
@@ -5,16 +5,18 @@ RSpec.describe Saml::Kit::UrlBuilder do
let(:xml) { "<xml></xml>" }
let(:destination) { FFaker::Internet.http_url }
let(:relay_state) { FFaker::Movie.title }
- let(:query_params) { Hash[result_uri.query.split("&").map { |x| x.split('=', 2) }] }
- let(:result) { subject.build(request, binding: :http_redirect, relay_state: relay_state) }
- let(:result_uri) { URI.parse(result) }
[
- Saml::Kit::AuthenticationRequest,
- Saml::Kit::LogoutRequest,
- ].each do |request_type|
- describe "AuthnRequest" do
- let(:request) { instance_double(request_type, destination: destination, to_xml: xml) }
+ [Saml::Kit::AuthenticationRequest, 'SAMLRequest'],
+ [Saml::Kit::LogoutRequest, 'SAMLRequest'],
+ [Saml::Kit::Response, 'SAMLResponse'],
+ [Saml::Kit::LogoutResponse, 'SAMLResponse'],
+ ].each do |(response_type, query_string_parameter)|
+ describe response_type.to_s do
+ let(:response) { instance_double(response_type, destination: destination, to_xml: xml, query_string_parameter: query_string_parameter) }
+ let(:result) { subject.build(response, binding: :http_redirect, relay_state: relay_state) }
+ let(:result_uri) { URI.parse(result) }
+ let(:query_params) { Hash[result_uri.query.split("&").map { |x| x.split('=', 2) }] }
it 'returns a url containing the target location' do
expect(result_uri.scheme).to eql("http")
@@ -24,8 +26,8 @@ RSpec.describe Saml::Kit::UrlBuilder do
it 'includes the message deflated (without header and checksum), base64-encoded, and URL-encoded' do
level = Zlib::BEST_COMPRESSION
expected = URI.encode(Base64.encode64(Zlib::Deflate.deflate(xml, level)[2..-5]).gsub(/\n/, ''))
- expect(result).to include("SAMLRequest=#{expected}")
- expect(query_params['SAMLRequest']).to eql(expected)
+ expect(result).to include("#{query_string_parameter}=#{expected}")
+ expect(query_params[query_string_parameter]).to eql(expected)
end
it 'includes the relay state' do
@@ -33,11 +35,10 @@ RSpec.describe Saml::Kit::UrlBuilder do
expect(result).to include("RelayState=#{URI.encode(relay_state)}")
end
- # https://docs.oasis-open.org/security/saml/v2.0/saml-bindings-2.0-os.pdf section 3.4.4.1
it 'includes a signature' do
expect(query_params['SigAlg']).to eql(URI.encode(Saml::Kit::Namespaces::SHA256))
- payload = "SAMLRequest=#{query_params['SAMLRequest']}"
+ payload = "#{query_string_parameter}=#{query_params[query_string_parameter]}"
payload << "&RelayState=#{query_params['RelayState']}"
payload << "&SigAlg=#{query_params['SigAlg']}"
expected_signature = Base64.strict_encode64(Saml::Kit.configuration.signing_private_key.sign(OpenSSL::Digest::SHA256.new, payload))