Commit 3b8db92
Changed files (3)
lib
saml
spec
saml
lib/saml/kit/authentication_request.rb
@@ -60,6 +60,12 @@ module Saml
Response::Builder.new(user, self).build
end
+ def trusted?
+ return false if provider.nil?
+ return false unless signed?
+ provider.matches?(fingerprint, use: :signing)
+ end
+
private
def registered_acs_url
@@ -82,8 +88,7 @@ module Saml
errors[:service_provider] << error_message(:unregistered)
return
end
- return if provider.matches?(fingerprint, use: :signing)
-
+ return if trusted?
errors[:fingerprint] << error_message(:invalid_fingerprint)
end
lib/saml/kit/response.rb
@@ -68,8 +68,8 @@ module Saml
content
end
- def encode
- Base64.strict_encode64(to_xml)
+ def serialize
+ Saml::Kit::Content.encode_raw_saml(to_xml)
end
def certificate
@@ -97,8 +97,20 @@ module Saml
Time.current > started_at && !expired?
end
- def self.deserialize(saml_response)
- new(Saml::Kit::Content.decode_raw_saml(saml_response))
+ def signed?
+ @xml_hash[name]['Signature'].present?
+ end
+
+ def trusted?
+ return false if provider.nil?
+ return false unless signed?
+ provider.matches?(fingerprint, use: :signing)
+ end
+
+ class << self
+ def deserialize(saml_response)
+ new(Saml::Kit::Content.decode_raw_saml(saml_response))
+ end
end
private
@@ -129,7 +141,7 @@ module Saml
def must_be_registered
return unless login_response?
- return if provider.present? && provider.matches?(fingerprint, use: :signing)
+ return if trusted?
errors[:base] << error_message(:unregistered)
end
@@ -186,6 +198,7 @@ module Saml
attr_reader :user, :request
attr_accessor :id, :reference_id, :now
attr_accessor :version, :status_code
+ attr_accessor :issuer
def initialize(user, request)
@user = user
@@ -195,19 +208,20 @@ module Saml
@now = Time.now.utc
@version = "2.0"
@status_code = Namespaces::SUCCESS
+ @issuer = configuration.issuer
end
def to_xml
signature = Signature.new(id)
xml = ::Builder::XmlMarkup.new
xml.Response response_options do
- xml.Issuer(configuration.issuer, xmlns: Namespaces::ASSERTION)
+ xml.Issuer(issuer, xmlns: Namespaces::ASSERTION)
signature.template(xml)
xml.Status do
xml.StatusCode Value: status_code
end
xml.Assertion(assertion_options) do
- xml.Issuer configuration.issuer
+ xml.Issuer issuer
xml.Subject do
xml.NameID user.name_id_for(request), Format: request.name_id_format
xml.SubjectConfirmation Method: Namespaces::BEARER do
@@ -224,10 +238,13 @@ module Saml
xml.AuthnContextClassRef Namespaces::PASSWORD
end
end
- xml.AttributeStatement do
- user.assertion_attributes_for(request).each do |key, value|
- xml.Attribute Name: key, NameFormat: Namespaces::URI, FriendlyName: key do
- xml.AttributeValue value.to_s
+ assertion_attributes = user.assertion_attributes_for(request)
+ if assertion_attributes.any?
+ xml.AttributeStatement do
+ assertion_attributes.each do |key, value|
+ xml.Attribute Name: key, NameFormat: Namespaces::URI, FriendlyName: key do
+ xml.AttributeValue value.to_s
+ end
end
end
end
spec/saml/response_spec.rb
@@ -222,4 +222,20 @@ RSpec.describe Saml::Kit::Response do
expect(subject.errors[:audience]).to be_present
end
end
+
+ describe "#serialize" do
+ let(:user) { double(:user, name_id_for: SecureRandom.uuid, assertion_attributes_for: { }) }
+ let(:request) { double(id: SecureRandom.uuid, acs_url: acs_url, issuer: issuer, name_id_format: Saml::Kit::Namespaces::PERSISTENT) }
+ let(:acs_url) { FFaker::Internet.http_url }
+ let(:issuer) { FFaker::Internet.http_url }
+
+ it 'returns a compressed and base64 encoded document' do
+ builder = described_class::Builder.new(user, request)
+ xml = builder.to_xml
+ subject = described_class.new(xml)
+
+ expected_value = Base64.encode64(Zlib::Deflate.deflate(xml, 9)).gsub(/\n/, '')
+ expect(subject.serialize).to eql(expected_value)
+ end
+ end
end