Commit 899fba9
Changed files (3)
lib
saml
lib/saml/kit/authentication_request.rb
@@ -1,12 +1,15 @@
module Saml
module Kit
class AuthenticationRequest
+ PROTOCOL_XSD = File.expand_path("./xsd/saml-schema-protocol-2.0.xsd", File.dirname(__FILE__)).freeze
+
include ActiveModel::Validations
validates_presence_of :content
validates_presence_of :acs_url, if: :login_request?
validate :must_be_request
validate :must_have_valid_signature
validate :must_be_registered_service_provider
+ validate :must_match_xsd
attr_reader :content, :name
@@ -82,6 +85,16 @@ module Saml
errors[:base] << error_message(:invalid) unless login_request?
end
+ def must_match_xsd
+ Dir.chdir(File.dirname(PROTOCOL_XSD)) do
+ xsd = Nokogiri::XML::Schema(IO.read(PROTOCOL_XSD))
+ document = Nokogiri::XML(to_xml)
+ xsd.validate(document).each do |error|
+ errors[:base] << error.message
+ end
+ end
+ end
+
def login_request?
return false if to_xml.blank?
@hash[name].present?
@@ -103,8 +116,8 @@ module Saml
def to_xml(xml = ::Builder::XmlMarkup.new)
signature = Signature.new(id)
xml.tag!('samlp:AuthnRequest', request_options) do
- signature.template(xml)
xml.tag!('saml:Issuer', issuer)
+ signature.template(xml)
xml.tag!('samlp:NameIDPolicy', Format: "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress")
end
signature.finalize(xml)
spec/saml/authentication_request_spec.rb
@@ -53,7 +53,8 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
end
it 'is valid when left untampered' do
- expect(described_class.new(raw_xml)).to be_valid
+ subject = described_class.new(raw_xml)
+ expect(subject).to be_valid
end
it 'is invalid if the document has been tampered with' do
@@ -107,6 +108,24 @@ RSpec.describe Saml::Kit::AuthenticationRequest do
expect(described_class.new(xml)).to be_valid
end
+
+ it 'validates the schema of the request' do
+ xml = ::Builder::XmlMarkup.new
+ id = SecureRandom.uuid
+ options = {
+ "xmlns:samlp" => Saml::Kit::Namespaces::PROTOCOL,
+ AssertionConsumerServiceURL: acs_url,
+ ID: "_#{id}",
+ }
+ signature = Saml::Kit::Signature.new(id)
+ xml.tag!('samlp:AuthnRequest', options) do
+ signature.template(xml)
+ xml.Fake do
+ xml.NotAllowed "Huh?"
+ end
+ end
+ expect(described_class.new(signature.finalize(xml))).to be_invalid
+ end
end
describe "#acs_url" do
spec/saml/default_registry_spec.rb
@@ -44,4 +44,6 @@ RSpec.describe Saml::Kit::DefaultRegistry do
expect(result).to be_instance_of(Saml::Kit::IdentityProviderMetadata)
end
end
+
+ xit 'registers metadata that serves as both an IDP and SP'
end