ruby-saml 0.9.4 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/LICENSE +1 -1
- data/README.md +71 -15
- data/changelog.md +15 -6
- data/lib/onelogin/ruby-saml.rb +1 -0
- data/lib/onelogin/ruby-saml/attribute_service.rb +25 -2
- data/lib/onelogin/ruby-saml/attributes.rb +42 -23
- data/lib/onelogin/ruby-saml/authrequest.rb +33 -8
- data/lib/onelogin/ruby-saml/http_error.rb +7 -0
- data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +65 -10
- data/lib/onelogin/ruby-saml/logging.rb +14 -10
- data/lib/onelogin/ruby-saml/logoutrequest.rb +39 -14
- data/lib/onelogin/ruby-saml/logoutresponse.rb +166 -39
- data/lib/onelogin/ruby-saml/metadata.rb +40 -23
- data/lib/onelogin/ruby-saml/response.rb +562 -88
- data/lib/onelogin/ruby-saml/saml_message.rb +80 -14
- data/lib/onelogin/ruby-saml/settings.rb +62 -23
- data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +210 -20
- data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +44 -13
- data/lib/onelogin/ruby-saml/utils.rb +163 -40
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/schemas/saml-schema-metadata-2.0.xsd +0 -2
- data/lib/xml_security.rb +87 -29
- data/ruby-saml.gemspec +1 -0
- data/test/certificates/{r1_certificate2_base64 → certificate_without_head_foot} +0 -0
- data/test/certificates/formatted_certificate +14 -0
- data/test/certificates/formatted_private_key +12 -0
- data/test/certificates/formatted_rsa_private_key +12 -0
- data/test/certificates/invalid_certificate1 +1 -0
- data/test/certificates/invalid_certificate2 +1 -0
- data/test/certificates/invalid_certificate3 +12 -0
- data/test/certificates/invalid_private_key1 +1 -0
- data/test/certificates/invalid_private_key2 +1 -0
- data/test/certificates/invalid_private_key3 +10 -0
- data/test/certificates/invalid_rsa_private_key1 +1 -0
- data/test/certificates/invalid_rsa_private_key2 +1 -0
- data/test/certificates/invalid_rsa_private_key3 +10 -0
- data/test/idp_metadata_parser_test.rb +41 -4
- data/test/logging_test.rb +62 -0
- data/test/logout_requests/invalid_slo_request.xml +6 -0
- data/test/{responses → logout_requests}/slo_request.xml +0 -0
- data/test/logout_requests/slo_request.xml.base64 +1 -0
- data/test/logout_requests/slo_request_deflated.xml.base64 +1 -0
- data/test/logout_requests/slo_request_with_session_index.xml +5 -0
- data/test/{responses → logout_responses}/logoutresponse_fixtures.rb +6 -6
- data/test/logoutrequest_test.rb +79 -52
- data/test/logoutresponse_test.rb +206 -59
- data/test/metadata_test.rb +77 -7
- data/test/request_test.rb +80 -65
- data/test/response_test.rb +862 -189
- data/test/responses/attackxee.xml +13 -0
- data/test/responses/invalids/invalid_audience.xml.base64 +1 -0
- data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +1 -0
- data/test/responses/invalids/invalid_issuer_message.xml.base64 +1 -0
- data/test/responses/invalids/invalid_signature_position.xml.base64 +1 -0
- data/test/responses/invalids/invalid_subjectconfirmation_inresponse.xml.base64 +1 -0
- data/test/responses/invalids/invalid_subjectconfirmation_nb.xml.base64 +1 -0
- data/test/responses/invalids/invalid_subjectconfirmation_noa.xml.base64 +1 -0
- data/test/responses/invalids/invalid_subjectconfirmation_recipient.xml.base64 +1 -0
- data/test/responses/invalids/multiple_assertions.xml.base64 +2 -0
- data/test/responses/invalids/multiple_signed.xml.base64 +1 -0
- data/test/responses/invalids/no_id.xml.base64 +1 -0
- data/test/responses/invalids/no_saml2.xml.base64 +1 -0
- data/test/responses/invalids/no_signature.xml.base64 +1 -0
- data/test/responses/invalids/no_status.xml.base64 +1 -0
- data/test/responses/invalids/no_status_code.xml.base64 +1 -0
- data/test/responses/invalids/no_subjectconfirmation_data.xml.base64 +1 -0
- data/test/responses/invalids/no_subjectconfirmation_method.xml.base64 +1 -0
- data/test/responses/invalids/response_encrypted_attrs.xml.base64 +1 -0
- data/test/responses/invalids/response_invalid_signed_element.xml.base64 +1 -0
- data/test/responses/invalids/status_code_responder.xml.base64 +1 -0
- data/test/responses/invalids/status_code_responer_and_msg.xml.base64 +1 -0
- data/test/responses/{response4.xml.base64 → response_assertion_wrapped.xml.base64} +0 -0
- data/test/responses/response_encrypted_nameid.xml.base64 +1 -0
- data/test/responses/response_unsigned_xml_base64 +1 -0
- data/test/responses/{response5.xml.base64 → response_with_saml2_namespace.xml.base64} +0 -0
- data/test/responses/{response3.xml.base64 → response_with_signed_assertion.xml.base64} +0 -0
- data/test/responses/{r1_response6.xml.base64 → response_with_signed_assertion_2.xml.base64} +0 -0
- data/test/responses/{response1.xml.base64 → response_with_undefined_recipient.xml.base64} +0 -0
- data/test/responses/{response2.xml.base64 → response_without_attributes.xml.base64} +0 -0
- data/test/responses/{wrapped_response_2.xml.base64 → response_wrapped.xml.base64} +0 -0
- data/test/responses/signed_message_encrypted_signed_assertion.xml.base64 +1 -0
- data/test/responses/signed_message_encrypted_unsigned_assertion.xml.base64 +1 -0
- data/test/responses/unsigned_message_aes128_encrypted_signed_assertion.xml.base64 +1 -0
- data/test/responses/unsigned_message_aes192_encrypted_signed_assertion.xml.base64 +1 -0
- data/test/responses/unsigned_message_aes256_encrypted_signed_assertion.xml.base64 +1 -0
- data/test/responses/unsigned_message_des192_encrypted_signed_assertion.xml.base64 +1 -0
- data/test/responses/unsigned_message_encrypted_assertion_without_saml_namespace.xml.base64 +1 -0
- data/test/responses/unsigned_message_encrypted_signed_assertion.xml.base64 +1 -0
- data/test/responses/unsigned_message_encrypted_unsigned_assertion.xml.base64 +1 -0
- data/test/responses/valid_response.xml.base64 +1 -0
- data/test/saml_message_test.rb +56 -0
- data/test/settings_test.rb +138 -1
- data/test/slo_logoutrequest_test.rb +239 -28
- data/test/slo_logoutresponse_test.rb +93 -71
- data/test/test_helper.rb +138 -31
- data/test/utils_test.rb +129 -25
- data/test/xml_security_test.rb +140 -71
- metadata +142 -25
- data/test/responses/response_node_text_attack.xml.base64 +0 -1
data/ruby-saml.gemspec
CHANGED
|
@@ -36,6 +36,7 @@ Gem::Specification.new do |s|
|
|
|
36
36
|
s.add_development_dependency('mocha', '~> 0.14')
|
|
37
37
|
s.add_development_dependency('rake', '~> 10')
|
|
38
38
|
s.add_development_dependency('shoulda', '~> 2.11')
|
|
39
|
+
s.add_development_dependency('simplecov','~> 0.9.0')
|
|
39
40
|
s.add_development_dependency('systemu', '~> 2')
|
|
40
41
|
s.add_development_dependency('timecop', '<= 0.6.0')
|
|
41
42
|
|
|
File without changes
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE
|
|
3
|
+
BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh
|
|
4
|
+
MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx
|
|
5
|
+
wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz
|
|
6
|
+
c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq
|
|
7
|
+
hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC
|
|
8
|
+
mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw
|
|
9
|
+
Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N
|
|
10
|
+
4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G
|
|
11
|
+
CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ
|
|
12
|
+
+4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1
|
|
13
|
+
2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
|
|
14
|
+
-----END CERTIFICATE-----
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
|
2
|
+
MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
|
|
3
|
+
NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
|
|
4
|
+
YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
|
|
5
|
+
hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
|
|
6
|
+
O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
|
|
7
|
+
B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
|
|
8
|
+
3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
|
|
9
|
+
d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
|
|
10
|
+
5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
|
|
11
|
+
GeW2AKaE6oqRqeVwGw4V
|
|
12
|
+
-----END PRIVATE KEY-----
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
|
2
|
+
MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
|
|
3
|
+
NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
|
|
4
|
+
YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
|
|
5
|
+
hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
|
|
6
|
+
O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
|
|
7
|
+
B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
|
|
8
|
+
3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
|
|
9
|
+
d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
|
|
10
|
+
5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
|
|
11
|
+
GeW2AKaE6oqRqeVwGw4V
|
|
12
|
+
-----END RSA PRIVATE KEY-----
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE----- MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ -----END CERTIFICATE-----
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UEBhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVhMDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIxwsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNzc28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jCmdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N 4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ +4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1 2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
MIICPDCCAaWgAwIBAgIIEiC/9HMAWWAwDQYJKoZIhvcNAQEFBQAwTzELMAkGA1UE
|
|
2
|
+
BhMCVVMxDDAKBgNVBAoTA2libTEMMAoGA1UECxMDc3NvMSQwIgYDVQQDExtjMjVh
|
|
3
|
+
MDI3Ny50b3JvbnRvLmNhLmlibS5jb20wHhcNMTEwNTI0MTYzNTQ4WhcNMjEwNTIx
|
|
4
|
+
wsQMPBj4WQTNzTYMCQYDVQQGEwJVUzEMMAoGA1UEChMDaWJtMQwwCgYDVQQLEwNz
|
|
5
|
+
c28xJDAiBgNVBAMTG2MyNWEwMjc3LnRvcm9udG8uY2EuaWJtLmNvbTCBnzANBgkq
|
|
6
|
+
hkiG9w0BAQEFAAOBjQAwgYkCgYEAgzfYQZuf5FVdJTcrsIQZ+YHTPjOsw2MGo0jC
|
|
7
|
+
mdGMcp4brWeFgk1OVaOmytPx6P76wHWR436AleX3crHBPd8gPxuZdnvBQ7PkrKpw
|
|
8
|
+
Vvaq52juenFrho8JY0TeVgVkY5jAh45YzytjP2y2k/cGQurI/56NT0PpQJ0S1G3N
|
|
9
|
+
4eTg718CAwEAAaMhMB8wHQYDVR0OBBYEFCYVLJqcJ7WgdzGIsuJ/TzDGDqinMA0G
|
|
10
|
+
CSqGSIb3DQEBBQUAA4GBAB80bIePf+qWDvWe+9bEEnbFTw7pCknLexxZ0AMqrsmZ
|
|
11
|
+
+4jmI+evP1JZYCjfIg9X+MBH01hfp5dFcetz3o6w6SkV+BxLYLgfcy5KUcYsIM/1
|
|
12
|
+
2Zkedj87bS1glzOy5B89pKD2DMbu6828Abzgc+4lyQ2ASifsqM4cZdVayzo8n+dQ
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
-----BEGIN PRIVATE KEY----- MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3 NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3 B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK GeW2AKaE6oqRqeVwGw4V -----END PRIVATE KEY-----
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUhtYzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfRhg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQRO1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOLd3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCKGeW2AKaE6oqRqeVwGw4V
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
|
|
2
|
+
NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
|
|
3
|
+
YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
|
|
4
|
+
hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
|
|
5
|
+
O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
|
|
6
|
+
B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
|
|
7
|
+
3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
|
|
8
|
+
d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
|
|
9
|
+
5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
|
|
10
|
+
GeW2AKaE6oqRqeVwGw4V
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY----- MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3 NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3 B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe 3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO 5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK GeW2AKaE6oqRqeVwGw4V -----END RSA PRIVATE KEY-----
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUhtYzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfRhg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQRO1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOLd3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCKGeW2AKaE6oqRqeVwGw4V
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
MIIBuwIBAAKBgQDImEj39zKfeh4LbgzPuos/DCnyKZUJzAHX3OSXA1Akl+CA1Ak3
|
|
2
|
+
NgRCJ3NOflCGzW+PcLvxrSwH3mHaqQAvDA2fJOySiVtJ9+tm1jrQnL+AAw7JzUht
|
|
3
|
+
YzmnRC8wwuN1+TDuKiK1Hzr/4fz2eFZ6+M53YC4eHOkBYA0FdFGRYrH70wIVAJfR
|
|
4
|
+
hg3tWWhJvyJBvaZoh3/BP613AoGBAL0KkMDFRc3FXcvdRKNpWbrsU41G32bBlfQR
|
|
5
|
+
O1EBe1+ghIasBr7lxEEhdkfthlaF4JiFHyaXuSx5hPKUbo8AO/MfaPJ7SKK2QRS3
|
|
6
|
+
B/qlstzIbjmvgYJJuOs4O4x6lYgeU5rb9G5SoOEBvyo46ZxfzdWhAwfZofsrzAhe
|
|
7
|
+
3WlOTZkdAoGAGmt0xlYn/0oYZjCxGKStjBA80E5NypAl7UyFj1RhGjIUkiuRcgOL
|
|
8
|
+
d3/fC6vKuqsMtLHyb5EGqtHPbqm4re1rw0zDh+qHEFA4N6UW0poc9eNEfosJA2BO
|
|
9
|
+
5o8ft9FzKA033pl89mD0CBj05EPadGR7E7QhL5mXuQJpjXJEiyqbce4CFAUFhvCK
|
|
10
|
+
GeW2AKaE6oqRqeVwGw4V
|
|
@@ -3,8 +3,17 @@ require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
|
|
3
3
|
require 'onelogin/ruby-saml/idp_metadata_parser'
|
|
4
4
|
|
|
5
5
|
class IdpMetadataParserTest < Minitest::Test
|
|
6
|
+
class MockSuccessResponse < Net::HTTPSuccess
|
|
7
|
+
# override parent's initialize
|
|
8
|
+
def initialize; end
|
|
9
|
+
|
|
10
|
+
attr_accessor :body
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class MockFailureResponse < Net::HTTPNotFound
|
|
14
|
+
# override parent's initialize
|
|
15
|
+
def initialize; end
|
|
6
16
|
|
|
7
|
-
class MockResponse
|
|
8
17
|
attr_accessor :body
|
|
9
18
|
end
|
|
10
19
|
|
|
@@ -24,7 +33,7 @@ class IdpMetadataParserTest < Minitest::Test
|
|
|
24
33
|
|
|
25
34
|
describe "download and parse IdP descriptor file" do
|
|
26
35
|
before do
|
|
27
|
-
mock_response =
|
|
36
|
+
mock_response = MockSuccessResponse.new
|
|
28
37
|
mock_response.body = idp_metadata
|
|
29
38
|
@url = "https://example.com"
|
|
30
39
|
uri = URI(@url)
|
|
@@ -34,7 +43,6 @@ class IdpMetadataParserTest < Minitest::Test
|
|
|
34
43
|
@http.expects(:request).returns(mock_response)
|
|
35
44
|
end
|
|
36
45
|
|
|
37
|
-
|
|
38
46
|
it "extract settings from remote xml" do
|
|
39
47
|
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
|
|
40
48
|
settings = idp_metadata_parser.parse_remote(@url)
|
|
@@ -49,10 +57,39 @@ class IdpMetadataParserTest < Minitest::Test
|
|
|
49
57
|
|
|
50
58
|
it "accept self signed certificate if insturcted" do
|
|
51
59
|
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
|
|
52
|
-
|
|
60
|
+
idp_metadata_parser.parse_remote(@url, false)
|
|
53
61
|
|
|
54
62
|
assert_equal OpenSSL::SSL::VERIFY_NONE, @http.verify_mode
|
|
55
63
|
end
|
|
56
64
|
end
|
|
57
65
|
|
|
66
|
+
describe "download failure cases" do
|
|
67
|
+
it "raises an exception when the url has no scheme" do
|
|
68
|
+
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
|
|
69
|
+
|
|
70
|
+
exception = assert_raises(ArgumentError) do
|
|
71
|
+
idp_metadata_parser.parse_remote("blahblah")
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
assert_equal("url must begin with http or https", exception.message)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it "raises an exception when unable to download metadata" do
|
|
78
|
+
mock_response = MockFailureResponse.new
|
|
79
|
+
@url = "https://example.com"
|
|
80
|
+
uri = URI(@url)
|
|
81
|
+
|
|
82
|
+
@http = Net::HTTP.new(uri.host, uri.port)
|
|
83
|
+
Net::HTTP.expects(:new).returns(@http)
|
|
84
|
+
@http.expects(:request).returns(mock_response)
|
|
85
|
+
|
|
86
|
+
idp_metadata_parser = OneLogin::RubySaml::IdpMetadataParser.new
|
|
87
|
+
|
|
88
|
+
exception = assert_raises(OneLogin::RubySaml::HttpError) do
|
|
89
|
+
idp_metadata_parser.parse_remote("https://example.hello.com/access/saml/idp.xml")
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
assert_equal("Failed to fetch idp metadata", exception.message)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
58
95
|
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
|
2
|
+
|
|
3
|
+
require 'onelogin/ruby-saml/logging'
|
|
4
|
+
|
|
5
|
+
class LoggingTest < Minitest::Test
|
|
6
|
+
|
|
7
|
+
describe "Logging" do
|
|
8
|
+
before do
|
|
9
|
+
OneLogin::RubySaml::Logging.logger = nil
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
after do
|
|
13
|
+
OneLogin::RubySaml::Logging.logger = ::TEST_LOGGER
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe "given no specific logging setup" do
|
|
17
|
+
it "prints to stdout" do
|
|
18
|
+
OneLogin::RubySaml::Logging::DEFAULT_LOGGER.expects(:debug).with('hi mom')
|
|
19
|
+
OneLogin::RubySaml::Logging.debug('hi mom')
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe "given a Rails app" do
|
|
24
|
+
let(:logger) { mock('Logger') }
|
|
25
|
+
|
|
26
|
+
before do
|
|
27
|
+
::Rails = mock('Rails module')
|
|
28
|
+
::Rails.stubs(:logger).returns(logger)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
after do
|
|
32
|
+
Object.instance_eval { remove_const(:Rails) }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "delegates to Rails" do
|
|
36
|
+
logger.expects(:debug).with('hi mom')
|
|
37
|
+
logger.expects(:info).with('sup?')
|
|
38
|
+
|
|
39
|
+
OneLogin::RubySaml::Logging.debug('hi mom')
|
|
40
|
+
OneLogin::RubySaml::Logging.info('sup?')
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe "given a specific Logger" do
|
|
45
|
+
let(:logger) { mock('Logger') }
|
|
46
|
+
|
|
47
|
+
before { OneLogin::RubySaml::Logging.logger = logger }
|
|
48
|
+
|
|
49
|
+
after do
|
|
50
|
+
OneLogin::RubySaml::Logging.logger = ::TEST_LOGGER
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
it "delegates to the object" do
|
|
54
|
+
logger.expects(:debug).with('hi mom')
|
|
55
|
+
logger.expects(:info).with('sup?')
|
|
56
|
+
|
|
57
|
+
OneLogin::RubySaml::Logging.debug('hi mom')
|
|
58
|
+
OneLogin::RubySaml::Logging.info('sup?')
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<samlp:LogoutRequest Version='2.0' ID='_c0348950-935b-0131-1060-782bcb56fcaa' xmlns:samlp='urn:oasis:names:tc:SAML:2.0:protocol' IssueInstant='2014-03-21T19:20:13'>
|
|
2
|
+
<saml:Issuer xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>https://app.onelogin.com/saml/metadata/SOMEACCOUNT</saml:Issuer>
|
|
3
|
+
<saml:Issuer xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>https://app.onelogin.com/saml/metadata/SOMEACCOUNT</saml:Issuer>
|
|
4
|
+
<saml:NameID xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>someone@example.org</saml:NameID>
|
|
5
|
+
<saml:NameID xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>someone2@example.org</saml:NameID>
|
|
6
|
+
</samlp:LogoutRequest>
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
PHNhbWxwOkxvZ291dFJlcXVlc3QgVmVyc2lvbj0nMi4wJyBJRD0nX2MwMzQ4OTUwLTkzNWItMDEzMS0xMDYwLTc4MmJjYjU2ZmNhYScgeG1sbnM6c2FtbHA9J3VybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDpwcm90b2NvbCcgSXNzdWVJbnN0YW50PScyMDE0LTAzLTIxVDE5OjIwOjEzJz4NCiAgPHNhbWw6SXNzdWVyIHhtbG5zOnNhbWw9J3VybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24nPmh0dHBzOi8vYXBwLm9uZWxvZ2luLmNvbS9zYW1sL21ldGFkYXRhL1NPTUVBQ0NPVU5UPC9zYW1sOklzc3Vlcj4NCiAgPHNhbWw6TmFtZUlEIHhtbG5zOnNhbWw9J3VybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24nPnNvbWVvbmVAZXhhbXBsZS5vcmc8L3NhbWw6TmFtZUlEPg0KPC9zYW1scDpMb2dvdXRSZXF1ZXN0Pg==
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
ndG7asMwFIDhvdB38KZJlmTHaSxs05B0COQCTdq1yKrqGqxLdWTI41dJOpgOHToKDv93DqpA6MHxre3sGJ7V16ggJK/KQ29NjbKUomSzrtGbpPlsURYUl3nRYspyhhmdU/ywyFrZFvMPKQRKznowwK/JGo3ecCugB26EVsCD5MflbstjlDtvg5V2iHWAUW0MBGFCBCmbYZrjjJ1YyTPKWY6a+7skqS5Rfh32E+ZvRQAoH+IlqPkMwQEnRDiXWqMG2/UmlVaTS4VoFcS7CIIcD7un5Wp1eNmfKjIhJzvsI7NZ/2cHsFpF+1GdhXaDSq3vfpBbMyK396//aL4B
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<samlp:LogoutRequest Version='2.0' ID='_c0348950-935b-0131-1060-782bcb56fcaa' xmlns:samlp='urn:oasis:names:tc:SAML:2.0:protocol' IssueInstant='2014-03-21T19:20:13'>
|
|
2
|
+
<saml:Issuer xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>https://app.onelogin.com/saml/metadata/SOMEACCOUNT</saml:Issuer>
|
|
3
|
+
<saml:NameID xmlns:saml='urn:oasis:names:tc:SAML:2.0:assertion'>someone@example.org</saml:NameID>
|
|
4
|
+
<samlp:SessionIndex>_ea853497-c58a-408a-bc23-c849752d9741</samlp:SessionIndex>
|
|
5
|
+
</samlp:LogoutRequest>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#encoding: utf-8
|
|
2
2
|
|
|
3
|
-
def
|
|
3
|
+
def default_logout_response_opts
|
|
4
4
|
{
|
|
5
5
|
:uuid => "_28024690-000e-0130-b6d2-38f6b112be8b",
|
|
6
6
|
:issue_instant => Time.now.strftime('%Y-%m-%dT%H:%M:%SZ'),
|
|
@@ -8,8 +8,8 @@ def default_response_opts
|
|
|
8
8
|
}
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
def
|
|
12
|
-
opts =
|
|
11
|
+
def valid_logout_response_document(opts = {})
|
|
12
|
+
opts = default_logout_response_opts.merge(opts)
|
|
13
13
|
|
|
14
14
|
"<samlp:LogoutResponse
|
|
15
15
|
xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
|
@@ -26,8 +26,8 @@ def valid_response(opts = {})
|
|
|
26
26
|
</samlp:LogoutResponse>"
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
def
|
|
30
|
-
opts =
|
|
29
|
+
def unsuccessful_logout_response_document(opts = {})
|
|
30
|
+
opts = default_logout_response_opts.merge(opts)
|
|
31
31
|
|
|
32
32
|
"<samlp:LogoutResponse
|
|
33
33
|
xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
|
@@ -44,7 +44,7 @@ def unsuccessful_response(opts = {})
|
|
|
44
44
|
</samlp:LogoutResponse>"
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
def
|
|
47
|
+
def invalid_xml_logout_response_document
|
|
48
48
|
"<samlp:SomethingAwful
|
|
49
49
|
xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
|
50
50
|
ID=\"#{random_id}\" Version=\"2.0\">
|
data/test/logoutrequest_test.rb
CHANGED
|
@@ -7,33 +7,32 @@ class RequestTest < Minitest::Test
|
|
|
7
7
|
describe "Logoutrequest" do
|
|
8
8
|
let(:settings) { OneLogin::RubySaml::Settings.new }
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
before do
|
|
11
11
|
settings.idp_slo_target_url = "http://unauth.com/logout"
|
|
12
12
|
settings.name_identifier_value = "f00f00"
|
|
13
|
+
end
|
|
13
14
|
|
|
15
|
+
it "create the deflated SAMLRequest URL parameter" do
|
|
14
16
|
unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings)
|
|
15
|
-
|
|
17
|
+
assert_match /^http:\/\/unauth\.com\/logout\?SAMLRequest=/, unauth_url
|
|
16
18
|
|
|
17
19
|
inflated = decode_saml_request_payload(unauth_url)
|
|
18
|
-
|
|
19
20
|
assert_match /^<samlp:LogoutRequest/, inflated
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
it "support additional params" do
|
|
23
|
-
settings.idp_slo_target_url = "http://example.com"
|
|
24
24
|
unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :hello => nil })
|
|
25
|
-
|
|
25
|
+
assert_match /&hello=$/, unauth_url
|
|
26
26
|
|
|
27
27
|
unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :foo => "bar" })
|
|
28
|
-
|
|
28
|
+
assert_match /&foo=bar$/, unauth_url
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
it "set sessionindex" do
|
|
32
|
-
settings.idp_slo_target_url = "http://example.com"
|
|
33
32
|
sessionidx = UUID.new.generate
|
|
34
33
|
settings.sessionindex = sessionidx
|
|
35
34
|
|
|
36
|
-
unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :
|
|
35
|
+
unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :nameid => "there" })
|
|
37
36
|
inflated = decode_saml_request_payload(unauth_url)
|
|
38
37
|
|
|
39
38
|
assert_match /<samlp:SessionIndex/, inflated
|
|
@@ -41,13 +40,11 @@ class RequestTest < Minitest::Test
|
|
|
41
40
|
end
|
|
42
41
|
|
|
43
42
|
it "set name_identifier_value" do
|
|
44
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
45
|
-
settings.idp_slo_target_url = "http://example.com"
|
|
46
43
|
settings.name_identifier_format = "transient"
|
|
47
44
|
name_identifier_value = "abc123"
|
|
48
45
|
settings.name_identifier_value = name_identifier_value
|
|
49
46
|
|
|
50
|
-
unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :
|
|
47
|
+
unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings, { :nameid => "there" })
|
|
51
48
|
inflated = decode_saml_request_payload(unauth_url)
|
|
52
49
|
|
|
53
50
|
assert_match /<saml:NameID/, inflated
|
|
@@ -56,31 +53,23 @@ class RequestTest < Minitest::Test
|
|
|
56
53
|
|
|
57
54
|
describe "when the target url doesn't contain a query string" do
|
|
58
55
|
it "create the SAMLRequest parameter correctly" do
|
|
59
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
60
|
-
settings.idp_slo_target_url = "http://example.com"
|
|
61
|
-
settings.name_identifier_value = "f00f00"
|
|
62
|
-
|
|
63
56
|
unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings)
|
|
64
|
-
|
|
57
|
+
assert_match /^http:\/\/unauth.com\/logout\?SAMLRequest/, unauth_url
|
|
65
58
|
end
|
|
66
59
|
end
|
|
67
60
|
|
|
68
61
|
describe "when the target url contains a query string" do
|
|
69
62
|
it "create the SAMLRequest parameter correctly" do
|
|
70
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
71
63
|
settings.idp_slo_target_url = "http://example.com?field=value"
|
|
72
|
-
settings.name_identifier_value = "f00f00"
|
|
73
64
|
|
|
74
65
|
unauth_url = OneLogin::RubySaml::Logoutrequest.new.create(settings)
|
|
75
|
-
|
|
66
|
+
assert_match /^http:\/\/example.com\?field=value&SAMLRequest/, unauth_url
|
|
76
67
|
end
|
|
77
68
|
end
|
|
78
69
|
|
|
79
70
|
describe "consumation of logout may need to track the transaction" do
|
|
80
71
|
it "have access to the request uuid" do
|
|
81
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
82
72
|
settings.idp_slo_target_url = "http://example.com?field=value"
|
|
83
|
-
settings.name_identifier_value = "f00f00"
|
|
84
73
|
|
|
85
74
|
unauth_req = OneLogin::RubySaml::Logoutrequest.new
|
|
86
75
|
unauth_url = unauth_req.create(settings)
|
|
@@ -91,15 +80,17 @@ class RequestTest < Minitest::Test
|
|
|
91
80
|
end
|
|
92
81
|
|
|
93
82
|
describe "when the settings indicate to sign (embedded) logout request" do
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
settings.idp_slo_target_url = "http://example.com?field=value"
|
|
97
|
-
settings.name_identifier_value = "f00f00"
|
|
83
|
+
|
|
84
|
+
before do
|
|
98
85
|
# sign the logout request
|
|
99
86
|
settings.security[:logout_requests_signed] = true
|
|
100
87
|
settings.security[:embed_sign] = true
|
|
101
88
|
settings.certificate = ruby_saml_cert_text
|
|
102
89
|
settings.private_key = ruby_saml_key_text
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
it "created a signed logout request" do
|
|
93
|
+
settings.compress_request = true
|
|
103
94
|
|
|
104
95
|
unauth_req = OneLogin::RubySaml::Logoutrequest.new
|
|
105
96
|
unauth_url = unauth_req.create(settings)
|
|
@@ -110,45 +101,49 @@ class RequestTest < Minitest::Test
|
|
|
110
101
|
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2000/09/xmldsig#sha1'/>], inflated
|
|
111
102
|
end
|
|
112
103
|
|
|
113
|
-
it "create a signed logout request with 256 digest and signature
|
|
114
|
-
settings = OneLogin::RubySaml::Settings.new
|
|
104
|
+
it "create a signed logout request with 256 digest and signature method" do
|
|
115
105
|
settings.compress_request = false
|
|
116
|
-
settings.idp_slo_target_url = "http://example.com?field=value"
|
|
117
|
-
settings.name_identifier_value = "f00f00"
|
|
118
|
-
# sign the logout request
|
|
119
|
-
settings.security[:logout_requests_signed] = true
|
|
120
|
-
settings.security[:embed_sign] = true
|
|
121
106
|
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
|
|
122
|
-
settings.security[:digest_method] = XMLSecurity::Document::
|
|
123
|
-
settings.certificate = ruby_saml_cert_text
|
|
124
|
-
settings.private_key = ruby_saml_key_text
|
|
107
|
+
settings.security[:digest_method] = XMLSecurity::Document::SHA256
|
|
125
108
|
|
|
126
109
|
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings)
|
|
127
110
|
request_xml = Base64.decode64(params["SAMLRequest"])
|
|
128
111
|
|
|
129
112
|
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], request_xml
|
|
130
113
|
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha256'/>], request_xml
|
|
114
|
+
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha256'/>], request_xml
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
it "create a signed logout request with 512 digest and signature method RSA_SHA384" do
|
|
118
|
+
settings.compress_request = false
|
|
119
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384
|
|
120
|
+
settings.security[:digest_method] = XMLSecurity::Document::SHA512
|
|
121
|
+
|
|
122
|
+
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings)
|
|
123
|
+
request_xml = Base64.decode64(params["SAMLRequest"])
|
|
124
|
+
|
|
125
|
+
assert_match %r[<ds:SignatureValue>([a-zA-Z0-9/+=]+)</ds:SignatureValue>], request_xml
|
|
126
|
+
assert_match %r[<ds:SignatureMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#rsa-sha384'/>], request_xml
|
|
131
127
|
assert_match %r[<ds:DigestMethod Algorithm='http://www.w3.org/2001/04/xmldsig-more#sha512'/>], request_xml
|
|
132
128
|
end
|
|
133
129
|
end
|
|
134
130
|
|
|
135
131
|
describe "#create_params when the settings indicate to sign the logout request" do
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
@cert = OpenSSL::X509::Certificate.new(ruby_saml_cert_text)
|
|
132
|
+
|
|
133
|
+
let(:cert) { OpenSSL::X509::Certificate.new(ruby_saml_cert_text) }
|
|
134
|
+
|
|
135
|
+
before do
|
|
136
|
+
# sign the logout request
|
|
137
|
+
settings.security[:logout_requests_signed] = true
|
|
138
|
+
settings.security[:embed_sign] = false
|
|
139
|
+
settings.certificate = ruby_saml_cert_text
|
|
140
|
+
settings.private_key = ruby_saml_key_text
|
|
146
141
|
end
|
|
147
142
|
|
|
148
|
-
it "create a signature parameter with RSA_SHA1 and validate it" do
|
|
143
|
+
it "create a signature parameter with RSA_SHA1 / SHA1 and validate it" do
|
|
149
144
|
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA1
|
|
150
145
|
|
|
151
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(
|
|
146
|
+
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
|
152
147
|
assert params['SAMLRequest']
|
|
153
148
|
assert params[:RelayState]
|
|
154
149
|
assert params['Signature']
|
|
@@ -160,13 +155,13 @@ class RequestTest < Minitest::Test
|
|
|
160
155
|
|
|
161
156
|
signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
|
|
162
157
|
assert_equal signature_algorithm, OpenSSL::Digest::SHA1
|
|
163
|
-
assert
|
|
158
|
+
assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
|
|
164
159
|
end
|
|
165
160
|
|
|
166
|
-
it "create a signature parameter with RSA_SHA256 and validate it" do
|
|
167
|
-
|
|
161
|
+
it "create a signature parameter with RSA_SHA256 / SHA256 and validate it" do
|
|
162
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA256
|
|
168
163
|
|
|
169
|
-
params = OneLogin::RubySaml::Logoutrequest.new.create_params(
|
|
164
|
+
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
|
170
165
|
assert params['Signature']
|
|
171
166
|
assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA256
|
|
172
167
|
|
|
@@ -176,7 +171,39 @@ class RequestTest < Minitest::Test
|
|
|
176
171
|
|
|
177
172
|
signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
|
|
178
173
|
assert_equal signature_algorithm, OpenSSL::Digest::SHA256
|
|
179
|
-
assert
|
|
174
|
+
assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it "create a signature parameter with RSA_SHA384 / SHA384 and validate it" do
|
|
178
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA384
|
|
179
|
+
|
|
180
|
+
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
|
181
|
+
assert params['Signature']
|
|
182
|
+
assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA384
|
|
183
|
+
|
|
184
|
+
query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
|
|
185
|
+
query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
|
|
186
|
+
query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
|
|
187
|
+
|
|
188
|
+
signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
|
|
189
|
+
assert_equal signature_algorithm, OpenSSL::Digest::SHA384
|
|
190
|
+
assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
it "create a signature parameter with RSA_SHA512 / SHA512 and validate it" do
|
|
194
|
+
settings.security[:signature_method] = XMLSecurity::Document::RSA_SHA512
|
|
195
|
+
|
|
196
|
+
params = OneLogin::RubySaml::Logoutrequest.new.create_params(settings, :RelayState => 'http://example.com')
|
|
197
|
+
assert params['Signature']
|
|
198
|
+
assert_equal params['SigAlg'], XMLSecurity::Document::RSA_SHA512
|
|
199
|
+
|
|
200
|
+
query_string = "SAMLRequest=#{CGI.escape(params['SAMLRequest'])}"
|
|
201
|
+
query_string << "&RelayState=#{CGI.escape(params[:RelayState])}"
|
|
202
|
+
query_string << "&SigAlg=#{CGI.escape(params['SigAlg'])}"
|
|
203
|
+
|
|
204
|
+
signature_algorithm = XMLSecurity::BaseDocument.new.algorithm(params['SigAlg'])
|
|
205
|
+
assert_equal signature_algorithm, OpenSSL::Digest::SHA512
|
|
206
|
+
assert cert.public_key.verify(signature_algorithm.new, Base64.decode64(params['Signature']), query_string)
|
|
180
207
|
end
|
|
181
208
|
|
|
182
209
|
end
|