Commit 7cf7b31
Changed files (3)
lib
saml
spec
lib/saml/kit/identity_provider_metadata.rb
@@ -1,12 +1,6 @@
module Saml
module Kit
- class IdentityProviderMetadata
- NAMESPACES = {
- "NameFormat": Namespaces::Formats::Attr::SPLAT,
- "ds": Namespaces::SIGNATURE,
- "md": Namespaces::METADATA,
- "saml": Namespaces::ASSERTION,
- }.freeze
+ class IdentityProviderMetadata < Metadata
METADATA_XSD = File.expand_path("./xsd/saml-schema-metadata-2.0.xsd", File.dirname(__FILE__)).freeze
include ActiveModel::Validations
@@ -16,7 +10,7 @@ module Saml
validate :must_have_valid_signature
def initialize(xml)
- @xml = xml
+ super("IDPSSODescriptor", xml)
end
def entity_id
@@ -41,18 +35,6 @@ module Saml
end
end
- def certificates
- xpath = "/md:EntityDescriptor/md:IDPSSODescriptor/md:KeyDescriptor"
- find_all(xpath).map do |item|
- cert = Base64.decode64(item.at_xpath("./ds:KeyInfo/ds:X509Data/ds:X509Certificate", NAMESPACES).text)
- {
- fingerprint: fingerprint_for(cert),
- use: item.attribute('use').value,
- value: cert,
- }
- end
- end
-
def attributes
find_all("/md:EntityDescriptor/md:IDPSSODescriptor/saml:Attribute").map do |item|
{
@@ -63,10 +45,6 @@ module Saml
end
end
- def to_xml
- @xml
- end
-
private
def error_message(key)
@@ -104,23 +82,6 @@ module Saml
result
end
- def fingerprint_for(value)
- x509 = OpenSSL::X509::Certificate.new(value)
- OpenSSL::Digest::SHA256.new.hexdigest(x509.to_der).upcase.scan(/../).join(":")
- end
-
- def document
- @document ||= Nokogiri::XML(@xml)
- end
-
- def find_by(xpath)
- document.at_xpath(xpath, NAMESPACES)
- end
-
- def find_all(xpath)
- document.search(xpath, NAMESPACES)
- end
-
class Builder
attr_accessor :id, :organization_name, :organization_url, :contact_email, :entity_id, :single_sign_on_location, :single_logout_location, :attributes
lib/saml/kit/metadata.rb
@@ -20,8 +20,8 @@ module Saml
find_all(xpath).map do |item|
cert = item.at_xpath("./ds:KeyInfo/ds:X509Data/ds:X509Certificate", NAMESPACES).text
{
- fingerprint: fingerprint_for(cert, OpenSSL::Digest::SHA256),
text: cert,
+ fingerprint: fingerprint_for(cert, OpenSSL::Digest::SHA256),
use: item.attribute('use').value,
}
end
spec/saml/identity_provider_metadata_spec.rb
@@ -65,7 +65,7 @@ RSpec.describe Saml::Kit::IdentityProviderMetadata do
expect(subject.certificates).to match_array([
{
use: "signing",
- value: Base64.decode64(certificate),
+ text: certificate,
fingerprint: "9F:74:13:3B:BC:5A:7B:8B:2D:4F:8B:EF:1E:88:EB:D1:AE:BC:19:BF:CA:19:C6:2F:0F:4B:31:1D:68:98:B0:1B",
}
])
@@ -75,29 +75,12 @@ RSpec.describe Saml::Kit::IdentityProviderMetadata do
context "active directory metadata" do
let(:raw_metadata) { IO.read("spec/fixtures/metadata/ad_with_logout.xml") }
+ let(:xml_hash) { Hash.from_xml(raw_metadata) }
let(:signing_certificate) do
- <<-EOS
-MIIC9DCCAdygAwIBAgIQPUYupdctSKhFxrjyD5572DANBgkqhkiG9w0BAQsFADA2MTQwMgYDVQQDEytBREZTIFNpZ25pbmcgLSBXSU4tOE5QU
-EcwME5BQlIuMms4c3NvLmxvY2FsMB4XDTE2MTAwNjIwMzUyMFoXDTE3MTAwNjIwMzUyMFowNjE0MDIGA1UEAxMrQURGUyBTaWduaW5nIC0gV0lOLThOUFBHMDBOQUJSLjJrOHNzb
-y5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKBy5neD7sTZ1LJ4ah5tBOYYXvLaTslgyCizqx7vRBsBi9Se+a2Wvo/0KuLe2LtTo4TGA9j0j/1fS4Je3zGDE
-3DJn4eodRH34XRIerHuTB8EzjarTE6uxWzpaLhnrzbfFi/BDVX7flf3YDavtmqWJGaKcI155zVl9+Iyp7YOXLpmZumsrVi5L8Xcb79C99T/ErMKS7tXLvBvPslKABqm7+09Btdu/
-JCpKpEL+dxKaGj2VRjz1nFgXZPZJ+37nPkThjt3IvAitYzQCIme926AXBoMnS09yG5QN9Y+i8Fk+2YbSkxQTf+6xnxk51NytIzF8VRumNjZu2moOp5THp+Um2UCAwEAATANBgkqh
-kiG9w0BAQsFAAOCAQEADzxFG5vtFjnz8SBicenB11wODN6+MP3p+WZGy69eJcig/mq8C4OnOSY9CnQNVhEVgEL8RRmx9TQ3CWrX4QACCQOS9RDlULdczGNnN3hqkj4m/AtyFisbT
-1f0U+fBK1W3rEo1IqL0b189O7dPDFDr4lmZq7rc9IkbkPEoIR+saC9krUkEf7wBL0pA7hB591Hk5pxx58L4V5qYADoPinOfHM7/7A2N3TC+L21HerIDSzIHdVNb5dQp0BwU+E7A/
-6DqRtw74SyjPVIoPC/2HDwwhuDmV0/ve5ADSl9yYh06hdOrGg0khlP65N38BbZGYMRaul/EeIZTYNbzSVfBNORtaQ==
-EOS
+ xml_hash['EntityDescriptor']['IDPSSODescriptor']['KeyDescriptor'].find { |x| x['use'] == 'signing' }['KeyInfo']['X509Data']['X509Certificate']
end
let(:encryption_certificate) do
- <<-EOS
-MIIC+jCCAeKgAwIBAgIQHjTznGekMIhCsGKTYQfDSjANBgkqhkiG9w0BAQsFADA5MTcwNQYDVQQDEy5BREZTIEVuY3J5cHRpb24gLSBXSU4tO
-E5QUEcwME5BQlIuMms4c3NvLmxvY2FsMB4XDTE2MTAwNjIwMzUyMVoXDTE3MTAwNjIwMzUyMVowOTE3MDUGA1UEAxMuQURGUyBFbmNyeXB0aW9uIC0gV0lOLThOUFBHMDBOQUJSL
-jJrOHNzby5sb2NhbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKx9AQ55jyNebZ/n5/WRx8FTQHtEOUUFfoaO6MogC79rsDBdnFrQZh718vTFIV69kRNI9olBlIShc
-q9OJ2ZIyA1l1o4aBE5VqUpDq+ReNnlsRmwRStGrwibmfPTQQmwcrO6EqjdIcANYHpOpcsqrP7+s7k1kKGE73nZCCzjlcA63xTJHhC1VmxogHnWOutXYVr1KHwGuWZIF6ElfoGorO
-maVq7IOrkAwtwHZXwGz7iD9AWiCZF9c9U+aroPCp0enUgZ4XFk59muYl8GReiRIL/D2Lk/WB6Bz5/5qyJlCcB+BJPMYCfLmllyzN17S2L6kCGEpqL9BhAXf5ZAJDTN1wJsCAwEAA
-TANBgkqhkiG9w0BAQsFAAOCAQEAD2frFw+c35baIX1b1daIU+9+o03pzJSLnCdMK0Fy/HAsHQGP8muKGCXdfFCy/cVZ8NxCXX9TsvtiXHyfasQ+H+RJVrer5zRhsQUn1mxP6vNGs
-hpY6cJqkXy1jrZA+af53P3ntUi4Ygu1ofzmleULHmK8m6zAGms1GT6ae82OoAfo7YOYwK5/QWWvOla4uF06fw8mfMRkKFEn/CFU1LAxaJ39tO+8/01VQe+bQaBGH7dmLhfkeMsi+
-oo3t+uQYdPuPP+WhpsVSEFqgMuzeoo2ZVbfvJUuQNiKvEx97VRe1CAhDasTIlkmN4Fj2Dxkia7nC1esYZd7YQ2LoeDGjyO7oA==
-EOS
+ xml_hash['EntityDescriptor']['IDPSSODescriptor']['KeyDescriptor'].find { |x| x['use'] == 'encryption' }['KeyInfo']['X509Data']['X509Certificate']
end
it { expect(subject.entity_id).to eql("https://win2008r2-ad-sso.qa1.immunet.com/adfs/services/trust") }
@@ -122,8 +105,16 @@ EOS
end
it do
expect(subject.certificates).to match_array([
- { use: 'signing', value: Base64.decode64(signing_certificate), fingerprint: "E6:03:E1:2D:F2:70:9C:D6:CC:8B:3E:4C:5A:37:F5:53:D7:B2:78:B1:2E:95:5B:31:5C:56:E8:7F:16:A1:1B:D2" },
- { use: 'encryption', value: Base64.decode64(encryption_certificate), fingerprint: "E1:0A:68:23:E4:17:32:A3:3A:F8:B7:30:A3:1D:D8:75:F4:C5:76:48:A4:C0:C8:D3:5E:F1:AE:AB:5B:B2:37:22" },
+ {
+ text: signing_certificate,
+ fingerprint: "E6:03:E1:2D:F2:70:9C:D6:CC:8B:3E:4C:5A:37:F5:53:D7:B2:78:B1:2E:95:5B:31:5C:56:E8:7F:16:A1:1B:D2",
+ use: 'signing',
+ },
+ {
+ text: encryption_certificate,
+ fingerprint: "E1:0A:68:23:E4:17:32:A3:3A:F8:B7:30:A3:1D:D8:75:F4:C5:76:48:A4:C0:C8:D3:5E:F1:AE:AB:5B:B2:37:22",
+ use: 'encryption',
+ },
])
end
it do
@@ -137,29 +128,12 @@ EOS
context "active directory windows server 2012 metadata" do
let(:raw_metadata) { IO.read("spec/fixtures/metadata/ad_2012.xml") }
+ let(:xml_hash) { Hash.from_xml(raw_metadata) }
let(:signing_certificate) do
-<<-EOS
-MIIC/DCCAeSgAwIBAgIQGobBMVmYz61AqNR/42A7NDANBgkqhkiG9w0BAQsFADA6MTgwNgYDVQQDEy9BREZTIFNpZ25pbmcgLSB3aW4yMDEyc
-jItYWQtc3NvLnFhMS5pbW11bmV0LmNvbTAeFw0xNjEwMjExNDUwMDRaFw0xNzEwMjExNDUwMDRaMDoxODA2BgNVBAMTL0FERlMgU2lnbmluZyAtIHdpbjIwMTJyMi1hZC1zc28uc
-WExLmltbXVuZXQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuvYden1ksmpxGGvnZGotnRwFCTOYknY4Ol0utUIYTYs/MTOZQtilSRWnsCFhPzUjXATMTF6kK
-uiH7LIow2QkYxv8JFMrc9FIUvxRauYJ/GVmedT9gMF2nh62Evi9DExDTM5xRM3bmircPB3cwg6M1BixcbvQtlRj37IEXEApk5ZAY24jivElnsQWwCIV9tLL9Kv4pBCDvQiZl6Bjk
-4ZRulyKolQDd9+S0tXISo+OaxQ6WwXbOFDIekUBgNE6ivXrbPH1+CP+paDAMB6vpj5C+o2c3rP9X53Dk4ig0mjw4mbOqd6p/S1Bs3cpNJb1F8RK9SgSxPIV7SIvI8u2FD+XdwIDA
-QABMA0GCSqGSIb3DQEBCwUAA4IBAQAlgP26UQUnC/3V1+ZlpCAWO6727MFNtsT/mue6PVEiydtjPurGF7cA4ljfk6E5QEB2U/Hhc4gh0VsbGTAP0g7m/BXAohaxG9S/1ITSj+8B/
-4IjLwQjUdPDuGcWHuRgOK84LMFj+Ial6zQUP1G4K0eQRFOEV3PeQVbyGDWBzxadFapN7k+BdDNJ1DgTDuEmJPmGAjHMM8I/m/G/UGQfCwZcB19pFPqhv+sV21D8BQ038y6j5Z3YX
-iIThdJ7LVTbOuN3dTXglgXIy0nPTx9YWGV9bf8hqVLwjYmsBRLH7lUoVxNjRkFeXCnbTrgT7AgG/94VlHtvnhJkCfQ3SMsAjwR3
-EOS
+ xml_hash['EntityDescriptor']['IDPSSODescriptor']['KeyDescriptor'].find { |x| x['use'] == 'signing' }['KeyInfo']['X509Data']['X509Certificate']
end
let(:encryption_certificate) do
-<<-EOS
-MIIDAjCCAeqgAwIBAgIQRra0nUbJhqFBNtFtXXUr4jANBgkqhkiG9w0BAQsFADA9MTswOQYDVQQDEzJBREZTIEVuY3J5cHRpb24gLSB3aW4yM
-DEycjItYWQtc3NvLnFhMS5pbW11bmV0LmNvbTAeFw0xNjEwMjExNDUwMDZaFw0xNzEwMjExNDUwMDZaMD0xOzA5BgNVBAMTMkFERlMgRW5jcnlwdGlvbiAtIHdpbjIwMTJyMi1hZ
-C1zc28ucWExLmltbXVuZXQuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqdQOAO/jAtq6Kbdq87+APchTXGNKKr2H168l7iVu7bH/QEtQJg2a3XD5wXwbwAOsM
-HbIzdZfaEqn4coB6O2kvombJHSl1+ZSz5bm1JV79afPdvfcfw1RBN7WXt59di3WCCN2dUD6l9FJWjI61B83BSFPsJIXYewhPJRmFV+nbFAVPjLr5wQXWIXm2e5JSxKwpAU3kNuUO
-q57O1IKLXvsqTrb0j+LJyCEs8uum3Ex+K/BAzPn4P8Xq6kRmsHLUCivXyjMHmA1T/4S+HMvTRI08O6zYUYbpNDUztzuxYOjjcDRCyLxbWBJIDv2KVoXG5iGF61CFLhtKaWw8mBPF
-7OqpQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBDoG1K4XC/xPU3/0BZ0i6DqjzsRhelFB5U9Ufhen+qdx0IjgHwb06U0mUst53kPuLy/uABGUqBololQmctx+RB9A5+6b6Cm6ZQP
-Nnxn2nopJNqT6VKKszsOnaphE6kVSFZUFOXQjezCIbyT22sBSa6lxG4wdun5vKThFh8tUDK1radniEKLrsdISgnVMl7KUYUlEDcy4hUOXR4DJkcbgryBgnP81pAUu01+0rfiLvJg
-pZnnhMRNYKrMC9X3jSdoSomh+SRV+Pld1j0QX3WambF38qd3AbQ/TXt8ytzh1NwIKkiRDGshkOwKItSbxEMLE2Qx1W4pal0e9J+An7+3eaB
-EOS
+ xml_hash['EntityDescriptor']['IDPSSODescriptor']['KeyDescriptor'].find { |x| x['use'] == 'encryption' }['KeyInfo']['X509Data']['X509Certificate']
end
it { expect(subject.entity_id).to eql("http://win2012r2-ad-sso.qa1.immunet.com/adfs/services/trust") }
@@ -184,8 +158,8 @@ EOS
end
it do
expect(subject.certificates).to match_array([
- { use: "signing", value: Base64.decode64(signing_certificate), fingerprint: "BE:12:70:84:AD:99:6A:58:28:2A:BC:DA:AB:E8:51:D3:FF:AB:58:30:E0:77:DB:23:57:15:01:B3:86:60:97:80" },
- { use: "encryption", value: Base64.decode64(encryption_certificate), fingerprint: "5C:51:0C:8A:6A:02:24:3C:9E:96:96:18:2E:37:65:8F:CC:EA:51:0E:2C:C5:3F:1D:72:47:11:D0:7B:95:26:1F" },
+ { use: "signing", text: signing_certificate, fingerprint: "BE:12:70:84:AD:99:6A:58:28:2A:BC:DA:AB:E8:51:D3:FF:AB:58:30:E0:77:DB:23:57:15:01:B3:86:60:97:80" },
+ { use: "encryption", text: encryption_certificate, fingerprint: "5C:51:0C:8A:6A:02:24:3C:9E:96:96:18:2E:37:65:8F:CC:EA:51:0E:2C:C5:3F:1D:72:47:11:D0:7B:95:26:1F" },
])
end
it { expect(subject.attributes).to be_present }