ruby-saml 0.9.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of ruby-saml might be problematic. Click here for more details.
- 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
|