ruby-saml 0.8.18 → 0.9
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/.travis.yml +1 -6
- data/Gemfile +2 -12
- data/README.md +363 -35
- data/Rakefile +14 -0
- data/changelog.md +22 -9
- data/lib/onelogin/ruby-saml/attribute_service.rb +34 -0
- data/lib/onelogin/ruby-saml/attributes.rb +26 -64
- data/lib/onelogin/ruby-saml/authrequest.rb +47 -93
- data/lib/onelogin/ruby-saml/idp_metadata_parser.rb +87 -0
- data/lib/onelogin/ruby-saml/logoutrequest.rb +36 -100
- data/lib/onelogin/ruby-saml/logoutresponse.rb +25 -35
- data/lib/onelogin/ruby-saml/metadata.rb +46 -16
- data/lib/onelogin/ruby-saml/response.rb +63 -373
- data/lib/onelogin/ruby-saml/saml_message.rb +78 -0
- data/lib/onelogin/ruby-saml/settings.rb +54 -122
- data/lib/onelogin/ruby-saml/slo_logoutrequest.rb +25 -71
- data/lib/onelogin/ruby-saml/slo_logoutresponse.rb +37 -102
- data/lib/onelogin/ruby-saml/utils.rb +32 -199
- data/lib/onelogin/ruby-saml/version.rb +1 -1
- data/lib/ruby-saml.rb +5 -2
- data/lib/schemas/{saml20assertion_schema.xsd → saml-schema-assertion-2.0.xsd} +283 -283
- data/lib/schemas/saml-schema-authn-context-2.0.xsd +23 -0
- data/lib/schemas/saml-schema-authn-context-types-2.0.xsd +821 -0
- data/lib/schemas/saml-schema-metadata-2.0.xsd +339 -0
- data/lib/schemas/{saml20protocol_schema.xsd → saml-schema-protocol-2.0.xsd} +302 -302
- data/lib/schemas/sstc-metadata-attr.xsd +35 -0
- data/lib/schemas/sstc-saml-attribute-ext.xsd +25 -0
- data/lib/schemas/sstc-saml-metadata-algsupport-v1.0.xsd +41 -0
- data/lib/schemas/sstc-saml-metadata-ui-v1.0.xsd +89 -0
- data/lib/schemas/{xenc_schema.xsd → xenc-schema.xsd} +1 -11
- data/lib/schemas/xml.xsd +287 -0
- data/lib/schemas/{xmldsig_schema.xsd → xmldsig-core-schema.xsd} +0 -9
- data/lib/xml_security.rb +83 -235
- data/ruby-saml.gemspec +1 -0
- data/test/idp_metadata_parser_test.rb +54 -0
- data/test/logoutrequest_test.rb +68 -155
- data/test/logoutresponse_test.rb +43 -32
- data/test/metadata_test.rb +87 -0
- data/test/request_test.rb +102 -99
- data/test/response_test.rb +181 -495
- data/test/responses/idp_descriptor.xml +3 -0
- data/test/responses/logoutresponse_fixtures.rb +7 -8
- data/test/responses/response_no_cert_and_encrypted_attrs.xml +29 -0
- data/test/responses/response_with_multiple_attribute_values.xml +1 -1
- data/test/responses/slo_request.xml +4 -0
- data/test/settings_test.rb +25 -112
- data/test/slo_logoutrequest_test.rb +40 -50
- data/test/slo_logoutresponse_test.rb +86 -185
- data/test/test_helper.rb +27 -102
- data/test/xml_security_test.rb +114 -337
- metadata +30 -81
- data/lib/onelogin/ruby-saml/setting_error.rb +0 -6
- data/test/certificates/certificate.der +0 -0
- data/test/certificates/formatted_certificate +0 -14
- data/test/certificates/formatted_chained_certificate +0 -42
- data/test/certificates/formatted_private_key +0 -12
- data/test/certificates/formatted_rsa_private_key +0 -12
- data/test/certificates/invalid_certificate1 +0 -1
- data/test/certificates/invalid_certificate2 +0 -1
- data/test/certificates/invalid_certificate3 +0 -12
- data/test/certificates/invalid_chained_certificate1 +0 -1
- data/test/certificates/invalid_private_key1 +0 -1
- data/test/certificates/invalid_private_key2 +0 -1
- data/test/certificates/invalid_private_key3 +0 -10
- data/test/certificates/invalid_rsa_private_key1 +0 -1
- data/test/certificates/invalid_rsa_private_key2 +0 -1
- data/test/certificates/invalid_rsa_private_key3 +0 -10
- data/test/certificates/ruby-saml-2.crt +0 -15
- data/test/requests/logoutrequest_fixtures.rb +0 -47
- data/test/responses/encrypted_new_attack.xml.base64 +0 -1
- data/test/responses/invalids/invalid_issuer_assertion.xml.base64 +0 -1
- data/test/responses/invalids/invalid_issuer_message.xml.base64 +0 -1
- data/test/responses/invalids/multiple_signed.xml.base64 +0 -1
- data/test/responses/invalids/no_signature.xml.base64 +0 -1
- data/test/responses/invalids/response_with_concealed_signed_assertion.xml +0 -51
- data/test/responses/invalids/response_with_doubled_signed_assertion.xml +0 -49
- data/test/responses/invalids/signature_wrapping_attack.xml.base64 +0 -1
- data/test/responses/response_node_text_attack.xml.base64 +0 -1
- data/test/responses/response_with_concealed_signed_assertion.xml +0 -51
- data/test/responses/response_with_doubled_signed_assertion.xml +0 -49
- data/test/responses/response_with_multiple_attribute_statements.xml +0 -72
- data/test/responses/response_with_signed_assertion_3.xml +0 -30
- data/test/responses/response_with_signed_message_and_assertion.xml +0 -34
- data/test/responses/response_with_undefined_recipient.xml.base64 +0 -1
- data/test/responses/response_wrapped.xml.base64 +0 -150
- data/test/responses/valid_response.xml.base64 +0 -1
- data/test/responses/valid_response_without_x509certificate.xml.base64 +0 -1
- data/test/utils_test.rb +0 -231
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<md:EntityDescriptor entityID="https://example.hello.com/access/saml/idp.xml" validUntil="2014-04-17T18:02:33.910Z" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"><md:IDPSSODescriptor WantAuthnRequestsSigned="true" protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol"><md:KeyDescriptor use="signing"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxekNDQXhTZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBRENCaGpFTE1Ba0dBMVVFQmhNQ1FWVXgKRERBS0JnTlZCQWdUQTA1VFZ6RVBNQTBHQTFVRUJ4TUdVM2xrYm1WNU1Rd3dDZ1lEVlFRS0RBTlFTVlF4Q1RBSApCZ05WQkFzTUFERVlNQllHQTFVRUF3d1BiR0YzY21WdVkyVndhWFF1WTI5dE1TVXdJd1lKS29aSWh2Y05BUWtCCkRCWnNZWGR5Wlc1alpTNXdhWFJBWjIxaGFXd3VZMjl0TUI0WERURXlNRFF4T1RJeU5UUXhPRm9YRFRNeU1EUXgKTkRJeU5UUXhPRm93Z1lZeEN6QUpCZ05WQkFZVEFrRlZNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVApCbE41Wkc1bGVURU1NQW9HQTFVRUNnd0RVRWxVTVFrd0J3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psCmJtTmxjR2wwTG1OdmJURWxNQ01HQ1NxR1NJYjNEUUVKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnYKYlRDQm56QU5CZ2txaGtpRzl3MEJBUUVGQUFPQmpRQXdnWWtDZ1lFQXFqaWUzUjJvaStwRGFldndJeXMvbWJVVApubkdsa3h0ZGlrcnExMXZleHd4SmlQTmhtaHFSVzNtVXVKRXpsbElkVkw2RW14R1lUcXBxZjkzSGxoa3NhZUowCjhVZ2pQOVVtTVlyaFZKdTFqY0ZXVjdmei9yKzIxL2F3VG5EVjlzTVlRcXVJUllZeTdiRzByMU9iaXdkb3ZudGsKN2dGSTA2WjB2WmFjREU1Ym9xVUNBd0VBQWFPQ0FTVXdnZ0VoTUFrR0ExVWRFd1FDTUFBd0N3WURWUjBQQkFRRApBZ1VnTUIwR0ExVWREZ1FXQkJTUk9OOEdKOG8rOGpnRnRqa3R3WmRxeDZCUnlUQVRCZ05WSFNVRUREQUtCZ2dyCkJnRUZCUWNEQVRBZEJnbGdoa2dCaHZoQ0FRMEVFQllPVkdWemRDQllOVEE1SUdObGNuUXdnYk1HQTFVZEl3U0IKcXpDQnFJQVVrVGpmQmlmS1B2STRCYlk1TGNHWGFzZWdVY21oZ1l5a2dZa3dnWVl4Q3pBSkJnTlZCQVlUQWtGVgpNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVEJsTjVaRzVsZVRFTU1Bb0dBMVVFQ2d3RFVFbFVNUWt3CkJ3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psYm1ObGNHbDBMbU52YlRFbE1DTUdDU3FHU0liM0RRRUoKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnZiWUlCQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9CZ1FDRQpUQWVKVERTQVc2ejFVRlRWN1FyZWg0VUxGT1JhajkrZUN1RjNLV0RIYyswSVFDajlyZG5ERzRRL3dmNy9yYVEwCkpuUFFDU0NkclBMSmV5b1BIN1FhVHdvYUY3ZHpWdzRMQ3N5TkpURld4NGNNNTBWdzZSNWZET2dpQzhic2ZmUzgKQkptb3VscnJaRE5OVmpHOG1XNmNMeHJZdlZRT3JSVmVjQ0ZJZ3NzQ2JBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
|
|
3
|
+
</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:KeyDescriptor use="encryption"><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:X509Data><ds:X509Certificate>LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURxekNDQXhTZ0F3SUJBZ0lCQVRBTkJna3Foa2lHOXcwQkFRc0ZBRENCaGpFTE1Ba0dBMVVFQmhNQ1FWVXgKRERBS0JnTlZCQWdUQTA1VFZ6RVBNQTBHQTFVRUJ4TUdVM2xrYm1WNU1Rd3dDZ1lEVlFRS0RBTlFTVlF4Q1RBSApCZ05WQkFzTUFERVlNQllHQTFVRUF3d1BiR0YzY21WdVkyVndhWFF1WTI5dE1TVXdJd1lKS29aSWh2Y05BUWtCCkRCWnNZWGR5Wlc1alpTNXdhWFJBWjIxaGFXd3VZMjl0TUI0WERURXlNRFF4T1RJeU5UUXhPRm9YRFRNeU1EUXgKTkRJeU5UUXhPRm93Z1lZeEN6QUpCZ05WQkFZVEFrRlZNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVApCbE41Wkc1bGVURU1NQW9HQTFVRUNnd0RVRWxVTVFrd0J3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psCmJtTmxjR2wwTG1OdmJURWxNQ01HQ1NxR1NJYjNEUUVKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnYKYlRDQm56QU5CZ2txaGtpRzl3MEJBUUVGQUFPQmpRQXdnWWtDZ1lFQXFqaWUzUjJvaStwRGFldndJeXMvbWJVVApubkdsa3h0ZGlrcnExMXZleHd4SmlQTmhtaHFSVzNtVXVKRXpsbElkVkw2RW14R1lUcXBxZjkzSGxoa3NhZUowCjhVZ2pQOVVtTVlyaFZKdTFqY0ZXVjdmei9yKzIxL2F3VG5EVjlzTVlRcXVJUllZeTdiRzByMU9iaXdkb3ZudGsKN2dGSTA2WjB2WmFjREU1Ym9xVUNBd0VBQWFPQ0FTVXdnZ0VoTUFrR0ExVWRFd1FDTUFBd0N3WURWUjBQQkFRRApBZ1VnTUIwR0ExVWREZ1FXQkJTUk9OOEdKOG8rOGpnRnRqa3R3WmRxeDZCUnlUQVRCZ05WSFNVRUREQUtCZ2dyCkJnRUZCUWNEQVRBZEJnbGdoa2dCaHZoQ0FRMEVFQllPVkdWemRDQllOVEE1SUdObGNuUXdnYk1HQTFVZEl3U0IKcXpDQnFJQVVrVGpmQmlmS1B2STRCYlk1TGNHWGFzZWdVY21oZ1l5a2dZa3dnWVl4Q3pBSkJnTlZCQVlUQWtGVgpNUXd3Q2dZRFZRUUlFd05PVTFjeER6QU5CZ05WQkFjVEJsTjVaRzVsZVRFTU1Bb0dBMVVFQ2d3RFVFbFVNUWt3CkJ3WURWUVFMREFBeEdEQVdCZ05WQkFNTUQyeGhkM0psYm1ObGNHbDBMbU52YlRFbE1DTUdDU3FHU0liM0RRRUoKQVF3V2JHRjNjbVZ1WTJVdWNHbDBRR2R0WVdsc0xtTnZiWUlCQVRBTkJna3Foa2lHOXcwQkFRc0ZBQU9CZ1FDRQpUQWVKVERTQVc2ejFVRlRWN1FyZWg0VUxGT1JhajkrZUN1RjNLV0RIYyswSVFDajlyZG5ERzRRL3dmNy9yYVEwCkpuUFFDU0NkclBMSmV5b1BIN1FhVHdvYUY3ZHpWdzRMQ3N5TkpURld4NGNNNTBWdzZSNWZET2dpQzhic2ZmUzgKQkptb3VscnJaRE5OVmpHOG1XNmNMeHJZdlZRT3JSVmVjQ0ZJZ3NzQ2JBPT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://example.hello.com/access/saml/logout" ResponseLocation="https://example.hello.com/access/saml/logout"/><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat><md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="https://example.hello.com/access/saml/login"/></md:IDPSSODescriptor></md:EntityDescriptor>
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
def default_response_opts
|
|
4
4
|
{
|
|
5
5
|
:uuid => "_28024690-000e-0130-b6d2-38f6b112be8b",
|
|
6
|
-
:uuid2 => "_48024690-100e-1130-e6d2-28f6b112be71",
|
|
7
6
|
:issue_instant => Time.now.strftime('%Y-%m-%dT%H:%M:%SZ'),
|
|
8
7
|
:settings => settings
|
|
9
8
|
}
|
|
@@ -14,11 +13,11 @@ def valid_response(opts = {})
|
|
|
14
13
|
|
|
15
14
|
"<samlp:LogoutResponse
|
|
16
15
|
xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
|
17
|
-
ID=\"#{
|
|
16
|
+
ID=\"#{random_id}\" Version=\"2.0\"
|
|
18
17
|
IssueInstant=\"#{opts[:issue_instant]}\"
|
|
19
|
-
Destination=\"#{opts[:settings].
|
|
20
|
-
InResponseTo=\"#{opts[:
|
|
21
|
-
<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].
|
|
18
|
+
Destination=\"#{opts[:settings].single_logout_service_url}\"
|
|
19
|
+
InResponseTo=\"#{opts[:uuid]}\">
|
|
20
|
+
<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].issuer}</saml:Issuer>
|
|
22
21
|
<samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
|
|
23
22
|
<samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
|
24
23
|
Value=\"urn:oasis:names:tc:SAML:2.0:status:Success\">
|
|
@@ -34,9 +33,9 @@ def unsuccessful_response(opts = {})
|
|
|
34
33
|
xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
|
35
34
|
ID=\"#{random_id}\" Version=\"2.0\"
|
|
36
35
|
IssueInstant=\"#{opts[:issue_instant]}\"
|
|
37
|
-
Destination=\"#{opts[:settings].
|
|
36
|
+
Destination=\"#{opts[:settings].single_logout_service_url}\"
|
|
38
37
|
InResponseTo=\"#{opts[:uuid]}\">
|
|
39
|
-
<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].
|
|
38
|
+
<saml:Issuer xmlns:saml=\"urn:oasis:names:tc:SAML:2.0:assertion\">#{opts[:settings].issuer}</saml:Issuer>
|
|
40
39
|
<samlp:Status xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\">
|
|
41
40
|
<samlp:StatusCode xmlns:samlp=\"urn:oasis:names:tc:SAML:2.0:protocol\"
|
|
42
41
|
Value=\"urn:oasis:names:tc:SAML:2.0:status:Requester\">
|
|
@@ -57,7 +56,7 @@ def settings
|
|
|
57
56
|
{
|
|
58
57
|
:assertion_consumer_service_url => "http://app.muda.no/sso/consume",
|
|
59
58
|
:single_logout_service_url => "http://app.muda.no/sso/consume_logout",
|
|
60
|
-
:
|
|
59
|
+
:issuer => "http://app.muda.no",
|
|
61
60
|
:sp_name_qualifier => "http://sso.muda.no",
|
|
62
61
|
:idp_sso_target_url => "http://sso.muda.no/sso",
|
|
63
62
|
:idp_slo_target_url => "http://sso.muda.no/slo",
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?><samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" Destination="https://vmwdemo.socialcast.com/saml/authenticate" ID="_f9fbcbf79715244c7ff909d8663d782e" InResponseTo="_4b4c72d0-eb5a-0131-0fec-0050568312b8" IssueInstant="2014-07-11T18:53:30.916Z" Version="2.0"><samlp:Status><samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></samlp:Status><saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="_fddb13c899036a90f920ddaac50fc0d6" IssueInstant="2014-07-11T18:53:30.916Z" Version="2.0"><saml:Issuer>https://hw6dldc.vmwdemo.com/SAAS/API/1.0/GET/metadata/idp.xml</saml:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
|
2
|
+
<ds:SignedInfo>
|
|
3
|
+
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
|
|
4
|
+
<ds:SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
|
|
5
|
+
<ds:Reference URI="#_fddb13c899036a90f920ddaac50fc0d6">
|
|
6
|
+
<ds:Transforms>
|
|
7
|
+
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
|
|
8
|
+
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><ec:InclusiveNamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" PrefixList="ds saml xenc xs xsi"/></ds:Transform>
|
|
9
|
+
</ds:Transforms>
|
|
10
|
+
<ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
|
|
11
|
+
<ds:DigestValue>HS49Xqi+JftXvslmp/boT9ixzp8=</ds:DigestValue>
|
|
12
|
+
</ds:Reference>
|
|
13
|
+
</ds:SignedInfo>
|
|
14
|
+
<ds:SignatureValue>
|
|
15
|
+
gdY9y3GNOgOqBOlEx981yILKAssUG79fXw639MJB3uJjLYokqY+Y5KFFtAU4FGvh/L6Romghx0is
|
|
16
|
+
rxukFkfw9coxKOhCoDZiaYPvvuC2qqhTwTAZ0Spvwuffrj3UwztSWbS6JGXtebo4ghKnae4hH5lF
|
|
17
|
+
tRawV9HnbLJmhL3cVPSu+7SF3iWov0PZyZczH1P6sZrYeX5X32h3RhXXxMi3kgHGWxaVTQmgTEgu
|
|
18
|
+
xN3GD7lnsf+WOAvdPAPgFrJjEGJZDd/MClS/x5ZwLnMZ82r7XHoFhiC47eq3Te+JE9qZvSbIs/om
|
|
19
|
+
dpuFSaFKxxdM8C+vHTRUDDaGckqckPc5Y7wlgA==
|
|
20
|
+
</ds:SignatureValue>
|
|
21
|
+
</ds:Signature><saml:Subject><saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" NameQualifier="https://hw6dldc.vmwdemo.com/SAAS/API/1.0/GET/metadata/idp.xml">akjoshi87+du@gmail.com</saml:NameID><saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer"><saml:SubjectConfirmationData InResponseTo="_4b4c72d0-eb5a-0131-0fec-0050568312b8" NotOnOrAfter="2014-07-11T18:56:50.916Z" Recipient="https://vmwdemo.socialcast.com/saml/authenticate"/></saml:SubjectConfirmation></saml:Subject><saml:Conditions NotBefore="2014-07-11T18:53:15.916Z" NotOnOrAfter="2014-07-11T18:56:50.916Z"><saml:AudienceRestriction><saml:Audience>vmwdemo.socialcast.com</saml:Audience></saml:AudienceRestriction></saml:Conditions><saml:AuthnStatement AuthnInstant="2014-07-11T18:53:30.916Z" SessionIndex="_876ca8142c7ba8126af3c90d952af251"><saml:AuthnContext><saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</saml:AuthnContextClassRef></saml:AuthnContext></saml:AuthnStatement><saml:AttributeStatement><saml:Attribute Name="first_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">Demo</saml:AttributeValue></saml:Attribute><saml:Attribute Name="email" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">akjoshi87+du@gmail.com</saml:AttributeValue></saml:Attribute><saml:Attribute Name="last_name" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic"><saml:AttributeValue xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xs:string">User</saml:AttributeValue></saml:Attribute><saml:EncryptedAttribute><xenc:EncryptedData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" Id="_2a1c0500932ae79e9f5ede82dccb57c6" Type="http://www.w3.org/2001/04/xmlenc#Element"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><xenc:EncryptedKey Id="_ff2d29836cd453cdfca94b69b630cf40"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/><xenc:CipherData><xenc:CipherValue>IdFfvxdt+YBaLSkWfcxuGqiPDyiQtpklGkJZFW+UoZXMhopZXmW/ekfEAf1VpzIlDlo3xwY2y8Rw
|
|
22
|
+
zZwASwjiuHoQSMZQzZ6Ws184f1pWh9un23wgHzYc/jwXF0pXfcVL944SSxxNO4zO+DMJz6Px9rvk
|
|
23
|
+
Rpac86uujfBuqXlo684=</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData><xenc:CipherValue>/+Noi1tNN1HcY+bW/iyBkwOYR4X32pTPzq7EjQO/HB3L0B2RtpsYkvC9750eb6KydbsBSGCyNt3k
|
|
24
|
+
grjcI1nUgvvY488NhIo9+PWv3MhAqnljKhDzl6AcfE00Lq3HA1FcTCwrE0VLjUV4NtztK2JVCZwu
|
|
25
|
+
ToViUJMlu1SGL8U7uRfsRpbrXoIEv1AwFHjz+XZgwD3nxl79iAcnm3FFX7nIkjUQIPPBWC/U4XJN
|
|
26
|
+
u+u5svSoUpIOFqdeNcDQUq5+P5lXT46O5LcULQrEY8xHNGToxOwINMOrU+rCgwyAVbP/SaY9ywYe
|
|
27
|
+
bxpESNkHmkjLAI7GBvLRRkTEE88Q6/uV9D1A5X3rT4BMQJ0N7BfgnOJ7IMga2Q9wU9oPuoCsqL9I
|
|
28
|
+
bP9IY1vCLcAAEsMR0EgZaInLCiLoXdmDHllSo2fyKQqBGxE+KpZhvVdCOVzLN3+TrW3k/xl/kx6w
|
|
29
|
+
AIPFlXd6TRVzmg==</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></saml:EncryptedAttribute></saml:AttributeStatement></saml:Assertion></samlp:Response>
|
|
@@ -0,0 +1,4 @@
|
|
|
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:LogoutRequest>
|
data/test/settings_test.rb
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
|
2
2
|
|
|
3
|
-
class SettingsTest <
|
|
3
|
+
class SettingsTest < Test::Unit::TestCase
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
context "Settings" do
|
|
6
|
+
setup do
|
|
7
7
|
@settings = OneLogin::RubySaml::Settings.new
|
|
8
8
|
end
|
|
9
|
-
|
|
9
|
+
should "should provide getters and settings" do
|
|
10
10
|
accessors = [
|
|
11
|
-
:
|
|
12
|
-
:
|
|
13
|
-
:
|
|
14
|
-
:
|
|
15
|
-
:
|
|
11
|
+
:idp_entity_id, :idp_sso_target_url, :idp_slo_target_url, :idp_cert, :idp_cert_fingerprint,
|
|
12
|
+
:issuer, :assertion_consumer_service_url, :assertion_consumer_service_binding,
|
|
13
|
+
:single_logout_service_url, :single_logout_service_binding,
|
|
14
|
+
:sp_name_qualifier, :name_identifier_format, :name_identifier_value,
|
|
15
|
+
:sessionindex, :attributes_index, :passive, :force_authn,
|
|
16
|
+
:compress_request, :double_quote_xml_attribute_values, :protocol_binding,
|
|
17
|
+
:security, :certificate, :private_key,
|
|
18
|
+
:authn_context, :authn_context_comparison, :authn_context_decl_ref,
|
|
19
|
+
:assertion_consumer_logout_service_url,
|
|
20
|
+
:assertion_consumer_logout_service_binding
|
|
16
21
|
]
|
|
17
22
|
|
|
18
23
|
accessors.each do |accessor|
|
|
@@ -20,9 +25,10 @@ class SettingsTest < Minitest::Test
|
|
|
20
25
|
@settings.send("#{accessor}=".to_sym, value)
|
|
21
26
|
assert_equal value, @settings.send(accessor)
|
|
22
27
|
end
|
|
28
|
+
|
|
23
29
|
end
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
should "create settings from hash" do
|
|
26
32
|
|
|
27
33
|
config = {
|
|
28
34
|
:assertion_consumer_service_url => "http://app.muda.no/sso",
|
|
@@ -32,6 +38,7 @@ class SettingsTest < Minitest::Test
|
|
|
32
38
|
:idp_slo_target_url => "http://sso.muda.no/slo",
|
|
33
39
|
:idp_cert_fingerprint => "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00",
|
|
34
40
|
:name_identifier_format => "urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
|
|
41
|
+
:attributes_index => 30,
|
|
35
42
|
:passive => true,
|
|
36
43
|
:protocol_binding => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST'
|
|
37
44
|
}
|
|
@@ -42,110 +49,16 @@ class SettingsTest < Minitest::Test
|
|
|
42
49
|
end
|
|
43
50
|
end
|
|
44
51
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
it "returns nil when the cert is nil" do
|
|
52
|
-
@settings.idp_cert = nil
|
|
53
|
-
assert_nil @settings.get_idp_cert
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "returns the certificate when it is valid" do
|
|
57
|
-
@settings.idp_cert = ruby_saml_cert_text
|
|
58
|
-
assert @settings.get_idp_cert.kind_of? OpenSSL::X509::Certificate
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
it "raises when the certificate is not valid" do
|
|
62
|
-
# formatted but invalid cert
|
|
63
|
-
@settings.idp_cert = read_certificate("formatted_certificate")
|
|
64
|
-
assert_raises(OpenSSL::X509::CertificateError) {
|
|
65
|
-
@settings.get_idp_cert
|
|
66
|
-
}
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
describe "#get_sp_cert" do
|
|
71
|
-
it "returns nil when the cert is an empty string" do
|
|
72
|
-
@settings.certificate = ""
|
|
73
|
-
assert_nil @settings.get_sp_cert
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
it "returns nil when the cert is nil" do
|
|
77
|
-
@settings.certificate = nil
|
|
78
|
-
assert_nil @settings.get_sp_cert
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
it "returns the certificate when it is valid" do
|
|
82
|
-
@settings.certificate = ruby_saml_cert_text
|
|
83
|
-
assert @settings.get_sp_cert.kind_of? OpenSSL::X509::Certificate
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
it "raises when the certificate is not valid" do
|
|
87
|
-
# formatted but invalid cert
|
|
88
|
-
@settings.certificate = read_certificate("formatted_certificate")
|
|
89
|
-
assert_raises(OpenSSL::X509::CertificateError) {
|
|
90
|
-
@settings.get_sp_cert
|
|
91
|
-
}
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
describe "#get_sp_key" do
|
|
96
|
-
it "returns nil when the private key is an empty string" do
|
|
97
|
-
@settings.private_key = ""
|
|
98
|
-
assert_nil @settings.get_sp_key
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it "returns nil when the private key is nil" do
|
|
102
|
-
@settings.private_key = nil
|
|
103
|
-
assert_nil @settings.get_sp_key
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
it "returns the private key when it is valid" do
|
|
107
|
-
@settings.private_key = ruby_saml_key_text
|
|
108
|
-
assert @settings.get_sp_key.kind_of? OpenSSL::PKey::RSA
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
it "raises when the private key is not valid" do
|
|
112
|
-
# formatted but invalid rsa private key
|
|
113
|
-
@settings.private_key = read_certificate("formatted_rsa_private_key")
|
|
114
|
-
assert_raises(OpenSSL::PKey::RSAError) {
|
|
115
|
-
@settings.get_sp_key
|
|
116
|
-
}
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
describe "#get_fingerprint" do
|
|
122
|
-
it "get the fingerprint value when cert and fingerprint in settings are nil" do
|
|
123
|
-
@settings.idp_cert_fingerprint = nil
|
|
124
|
-
@settings.idp_cert = nil
|
|
125
|
-
fingerprint = @settings.get_fingerprint
|
|
126
|
-
assert_nil fingerprint
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
it "get the fingerprint value when there is a cert at the settings" do
|
|
130
|
-
@settings.idp_cert_fingerprint = nil
|
|
131
|
-
@settings.idp_cert = ruby_saml_cert_text
|
|
132
|
-
fingerprint = @settings.get_fingerprint
|
|
133
|
-
assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
it "get the fingerprint value when there is a fingerprint at the settings" do
|
|
137
|
-
@settings.idp_cert_fingerprint = ruby_saml_cert_fingerprint
|
|
138
|
-
@settings.idp_cert = nil
|
|
139
|
-
fingerprint = @settings.get_fingerprint
|
|
140
|
-
assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
|
|
52
|
+
should "configure attribute service attributes correctly" do
|
|
53
|
+
@settings = OneLogin::RubySaml::Settings.new
|
|
54
|
+
@settings.attribute_consuming_service.configure do
|
|
55
|
+
service_name "Test Service"
|
|
56
|
+
add_attribute :name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name"
|
|
141
57
|
end
|
|
142
58
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
fingerprint = @settings.get_fingerprint
|
|
147
|
-
assert fingerprint.downcase == ruby_saml_cert_fingerprint.downcase
|
|
148
|
-
end
|
|
59
|
+
assert_equal @settings.attribute_consuming_service.configured?, true
|
|
60
|
+
assert_equal @settings.attribute_consuming_service.name, "Test Service"
|
|
61
|
+
assert_equal @settings.attribute_consuming_service.attributes, [{:name => "Name", :name_format => "Name Format", :friendly_name => "Friendly Name" }]
|
|
149
62
|
end
|
|
150
63
|
|
|
151
64
|
end
|
|
@@ -1,71 +1,61 @@
|
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), "test_helper"))
|
|
2
|
-
require
|
|
2
|
+
require 'responses/logoutresponse_fixtures'
|
|
3
3
|
|
|
4
|
-
class
|
|
4
|
+
class RubySamlTest < Test::Unit::TestCase
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
context "SloLogoutrequest" do
|
|
7
|
+
should "raise an exception when response is initialized with nil" do
|
|
8
|
+
assert_raises(ArgumentError) { OneLogin::RubySaml::SloLogoutrequest.new(nil) }
|
|
9
|
+
end
|
|
7
10
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
it "default to empty settings" do
|
|
13
|
-
logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request)
|
|
14
|
-
assert logoutrequest.settings.nil?
|
|
15
|
-
end
|
|
16
|
-
it "accept constructor-injected settings" do
|
|
17
|
-
logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request, settings)
|
|
18
|
-
assert !logoutrequest.settings.nil?
|
|
19
|
-
end
|
|
20
|
-
it "accept constructor-injected options" do
|
|
21
|
-
logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request, nil, { :foo => :bar} )
|
|
22
|
-
assert !logoutrequest.options.empty?
|
|
11
|
+
context "#is_valid?" do
|
|
12
|
+
should "return false when response is initialized with blank data" do
|
|
13
|
+
request = OneLogin::RubySaml::SloLogoutrequest.new('')
|
|
14
|
+
assert !request.is_valid?
|
|
23
15
|
end
|
|
24
|
-
it "support base64 encoded requests" do
|
|
25
|
-
expected_request = valid_request
|
|
26
|
-
logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(Base64.encode64(expected_request), settings)
|
|
27
16
|
|
|
28
|
-
|
|
17
|
+
should "return true when the request is initialized with valid data" do
|
|
18
|
+
request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
|
|
19
|
+
assert request.is_valid?
|
|
20
|
+
assert_equal 'someone@example.org', request.name_id
|
|
29
21
|
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
describe "#validate" do
|
|
33
|
-
it "validate the request" do
|
|
34
|
-
in_relation_to_request_id = random_id
|
|
35
|
-
settings.idp_entity_id = "https://example.com/idp"
|
|
36
|
-
logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request({:uuid => in_relation_to_request_id}), settings)
|
|
37
|
-
|
|
38
|
-
assert logoutrequest.validate
|
|
39
22
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
23
|
+
should "should be idempotent when the response is initialized with invalid data" do
|
|
24
|
+
request = OneLogin::RubySaml::SloLogoutrequest.new(invalid_xml_response)
|
|
25
|
+
assert !request.is_valid?
|
|
26
|
+
assert !request.is_valid?
|
|
27
|
+
end
|
|
43
28
|
|
|
44
|
-
|
|
29
|
+
should "should be idempotent when the response is initialized with valid data" do
|
|
30
|
+
request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
|
|
31
|
+
assert request.is_valid?
|
|
32
|
+
assert request.is_valid?
|
|
45
33
|
end
|
|
46
34
|
|
|
35
|
+
should "raise error for invalid xml" do
|
|
36
|
+
logout_request = OneLogin::RubySaml::SloLogoutrequest.new(invalid_xml_response)
|
|
37
|
+
assert_raises(OneLogin::RubySaml::ValidationError) { logout_request.validate! }
|
|
38
|
+
end
|
|
47
39
|
end
|
|
48
40
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
logoutrequest = OneLogin::RubySaml::SloLogoutrequest.new(valid_request({:uuid => in_relation_to_request_id}), settings)
|
|
54
|
-
|
|
55
|
-
logoutrequest.validate!
|
|
41
|
+
context "#name_id" do
|
|
42
|
+
should "extract the value of the name id element" do
|
|
43
|
+
request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
|
|
44
|
+
assert_equal "someone@example.org", request.name_id
|
|
56
45
|
end
|
|
46
|
+
end
|
|
57
47
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
48
|
+
context "#issuer" do
|
|
49
|
+
should "return the issuer inside the request" do
|
|
50
|
+
request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
|
|
51
|
+
assert_equal "https://app.onelogin.com/saml/metadata/SOMEACCOUNT", request.issuer
|
|
62
52
|
end
|
|
63
53
|
end
|
|
64
54
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
assert_equal "
|
|
55
|
+
context "#id" do
|
|
56
|
+
should "extract the value of the ID attribute" do
|
|
57
|
+
request = OneLogin::RubySaml::SloLogoutrequest.new(logout_request_document)
|
|
58
|
+
assert_equal "_c0348950-935b-0131-1060-782bcb56fcaa", request.id
|
|
69
59
|
end
|
|
70
60
|
end
|
|
71
61
|
|