1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
|
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
require 'onelogin/ruby-saml/metadata'
class MetadataTest < Minitest::Test
describe 'Metadata' do
let(:settings) { OneLogin::RubySaml::Settings.new }
let(:xml_text) { OneLogin::RubySaml::Metadata.new.generate(settings, false) }
let(:xml_doc) { REXML::Document.new(xml_text) }
let(:spsso_descriptor) { REXML::XPath.first(xml_doc, "//md:SPSSODescriptor") }
let(:acs) { REXML::XPath.first(xml_doc, "//md:AssertionConsumerService") }
before do
settings.issuer = "https://example.com"
settings.name_identifier_format = "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress"
settings.assertion_consumer_service_url = "https://foo.example/saml/consume"
end
it "generates Pretty Print Service Provider Metadata" do
xml_text = OneLogin::RubySaml::Metadata.new.generate(settings, true)
# assert correct xml declaration
start = "<?xml version='1.0' encoding='UTF-8'?>\n<md:EntityDescriptor"
assert_equal xml_text[0..start.length-1],start
assert_equal "https://example.com", REXML::XPath.first(xml_doc, "//md:EntityDescriptor").attribute("entityID").value
assert_equal "urn:oasis:names:tc:SAML:2.0:protocol", spsso_descriptor.attribute("protocolSupportEnumeration").value
assert_equal "false", spsso_descriptor.attribute("AuthnRequestsSigned").value
assert_equal "false", spsso_descriptor.attribute("WantAssertionsSigned").value
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", REXML::XPath.first(xml_doc, "//md:NameIDFormat").text.strip
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", acs.attribute("Binding").value
assert_equal "https://foo.example/saml/consume", acs.attribute("Location").value
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
end
it "generates Service Provider Metadata" do
settings.single_logout_service_binding = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
settings.single_logout_service_url = "https://foo.example/saml/sls"
xml_metadata = OneLogin::RubySaml::Metadata.new.generate(settings, false)
start = "<?xml version='1.0' encoding='UTF-8'?><md:EntityDescriptor"
assert_equal xml_metadata[0..start.length-1],start
doc_metadata = REXML::Document.new(xml_metadata)
sls = REXML::XPath.first(doc_metadata, "//md:SingleLogoutService")
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect", sls.attribute("Binding").value
assert_equal "https://foo.example/saml/sls", sls.attribute("Location").value
assert_equal "https://foo.example/saml/sls", sls.attribute("ResponseLocation").value
assert_nil sls.attribute("isDefault")
assert_nil sls.attribute("index")
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
end
it "generates Service Provider Metadata with single logout service" do
start = "<?xml version='1.0' encoding='UTF-8'?><md:EntityDescriptor"
assert_equal xml_text[0..start.length-1], start
assert_equal "https://example.com", REXML::XPath.first(xml_doc, "//md:EntityDescriptor").attribute("entityID").value
assert_equal "urn:oasis:names:tc:SAML:2.0:protocol", spsso_descriptor.attribute("protocolSupportEnumeration").value
assert_equal "false", spsso_descriptor.attribute("AuthnRequestsSigned").value
assert_equal "false", spsso_descriptor.attribute("WantAssertionsSigned").value
assert_equal "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", REXML::XPath.first(xml_doc, "//md:NameIDFormat").text.strip
assert_equal "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST", acs.attribute("Binding").value
assert_equal "https://foo.example/saml/consume", acs.attribute("Location").value
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
end
describe "WantAssertionsSigned" do
it "generates Service Provider Metadata with WantAssertionsSigned = false" do
settings.security[:want_assertions_signed] = false
assert_equal "false", spsso_descriptor.attribute("WantAssertionsSigned").value
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
end
it "generates Service Provider Metadata with WantAssertionsSigned = true" do
settings.security[:want_assertions_signed] = true
assert_equal "true", spsso_descriptor.attribute("WantAssertionsSigned").value
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
end
end
describe "when auth requests are signed" do
let(:key_descriptors) do
REXML::XPath.match(
xml_doc,
"//md:KeyDescriptor",
"md" => "urn:oasis:names:tc:SAML:2.0:metadata"
)
end
let(:cert_nodes) do
REXML::XPath.match(
xml_doc,
"//md:KeyDescriptor/ds:KeyInfo/ds:X509Data/ds:X509Certificate",
"md" => "urn:oasis:names:tc:SAML:2.0:metadata",
"ds" => "http://www.w3.org/2000/09/xmldsig#"
)
end
let(:cert) { OpenSSL::X509::Certificate.new(Base64.decode64(cert_nodes[0].text)) }
before do
settings.certificate = ruby_saml_cert_text
end
it "generates Service Provider Metadata with AuthnRequestsSigned" do
settings.security[:authn_requests_signed] = true
assert_equal "true", spsso_descriptor.attribute("AuthnRequestsSigned").value
assert_equal ruby_saml_cert.to_der, cert.to_der
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
end
it "generates Service Provider Metadata with X509Certificate for sign and encrypt" do
assert_equal 2, key_descriptors.length
assert_equal "signing", key_descriptors[0].attribute("use").value
assert_equal "encryption", key_descriptors[1].attribute("use").value
assert_equal 2, cert_nodes.length
assert_equal ruby_saml_cert.to_der, cert.to_der
assert_equal cert_nodes[0].text, cert_nodes[1].text
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
end
end
describe "when attribute service is configured" do
let(:attr_svc) { REXML::XPath.first(xml_doc, "//md:AttributeConsumingService") }
let(:req_attr) { REXML::XPath.first(xml_doc, "//md:RequestedAttribute") }
before do
settings.attribute_consuming_service.configure do
service_name "Test Service"
add_attribute(:name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name", :attribute_value => "Attribute Value")
end
end
it "generates attribute service" do
assert_equal "true", attr_svc.attribute("isDefault").value
assert_equal "1", attr_svc.attribute("index").value
assert_equal REXML::XPath.first(xml_doc, "//md:ServiceName").text.strip, "Test Service"
assert_equal "Name", req_attr.attribute("Name").value
assert_equal "Name Format", req_attr.attribute("NameFormat").value
assert_equal "Friendly Name", req_attr.attribute("FriendlyName").value
assert_equal "Attribute Value", REXML::XPath.first(xml_doc, "//saml:AttributeValue").text.strip
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
end
describe "#service_name" do
before do
settings.attribute_consuming_service.service_name("Test2 Service")
end
it "change service name" do
assert_equal REXML::XPath.first(xml_doc, "//md:ServiceName").text.strip, "Test2 Service"
end
end
describe "#service_index" do
before do
settings.attribute_consuming_service.service_index(2)
end
it "change service index" do
assert_equal "2", attr_svc.attribute("index").value
end
end
end
describe "when the settings indicate to sign (embedded) metadata" do
before do
settings.security[:metadata_signed] = true
settings.certificate = ruby_saml_cert_text
settings.private_key = ruby_saml_key_text
end
it "creates a signed metadata" do
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>]m, xml_text
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1'/>], xml_text
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], xml_text
signed_metadata = XMLSecurity::SignedDocument.new(xml_text)
assert signed_metadata.validate_document(ruby_saml_cert_fingerprint, false)
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
end
describe "when digest and signature methods are specified" do
before do
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
settings.security[:digest_method] = XMLSecurity::Document::SHA512
end
it "creates a signed metadata with specified digest and signature methods" do
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>]m, xml_text
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], xml_text
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmlenc#sha512'/>], xml_text
signed_metadata_2 = XMLSecurity::SignedDocument.new(xml_text)
assert signed_metadata_2.validate_document(ruby_saml_cert_fingerprint, false)
assert validate_xml!(xml_text, "saml-schema-metadata-2.0.xsd")
end
end
end
end
end
|